Here's the traceback for Error: release unlocked lock Traceback (innermost last): File V:\src\ZopeRoot\lib\python\ZPublisher\Publish.py, line 214, in publish_module File V:\src\ZopeRoot\lib\python\ZPublisher\Publish.py, line 179, in publish File V:\src\ZopeRoot\lib\python\Zope\__init__.py, line 202, in zpublisher_exception_hook (Object: RoleManager) File V:\src\ZopeRoot\lib\python\ZPublisher\Publish.py, line 169, in publish File V:\src\ZopeRoot\lib\python\ZODB\Transaction.py, line 275, in commit File V:\src\ZopeRoot\lib\python\ZODB\Connection.py, line 467, in tpc_finish File V:\src\ZopeRoot\lib\python\ZODB\BaseStorage.py, line 202, in tpc_finish (Object: V:\src\ZopeRoot/var/Data.fs) The traceback appears in the browser, while the error message below appears on the console. After this, the application is unresponsive. The only reason I got a new connection was that I didn't know how to get the old one (or if it was safe to reuse it). Is there a canonical way to get Zope's connection? I tried again using Zope.app()._p_jar. (I had thought Zope.app() returned an application wrapper, and gave up when it didn't). This produces the connection, but leads to the same error. Other points: After this failure, the key of the object I am trying to insert appears in my OrgUserDirectory, and the value is of the right type (OrgUser). But the value has nothing in it. The standard Zope users do seem to be created (see below). I am able to create the error immediately by executing get_transaction.commit() in the debugger after my code finishes its normal execution. I tried del root['OrgUser'] in hopes that a new one would work better. It didn't. Some files are hanging around var/, even after a regular shutdown, which look a bit odd. Here's a listing: Directory of V:\src\ZopeRoot\var 01/17/00 02:15p 144,466 Data.fs 01/17/00 02:18p 1,971 Data.fs.index 01/17/00 02:18p 3 Data.fs.lock 01/17/00 02:16p 0 Data.fs.tmp 12/04/99 12:30p <DIR> gadfly 01/17/00 02:16p 3 pcgi.pid 01/17/00 02:17p 374,745 Z2.log 01/17/00 02:16p 3 Z2.pid 10 File(s) 521,191 bytes Here's the code I'm running, with some junk stripped out. The product creates OrgUserFolder. Some dtml then sends that object addOrgUser. This creates a regular zope user and then an OrgUserDirectory and an OrgUser, and puts the latter in the former. ---------------------------------- __init__.py ----------------------------------------------------------------- import OrgUser def initialize(context): try: context.registerClass( OrgUser.OrgUserFolder, constructors=(OrgUser.manage_addUserFolder, ) ) [except clause omited] --------------------------------- OrgUser.py------------------------------------------------------------------- import Globals from Globals import HTMLFile, MessageDialog import Persistence from AccessControl.User import UserFolder import Zope # for app for database manage_addUserForm = HTMLFile('addUser', globals()) class OrgUser(Persistence.Persistent): """Add additional information on the user""" meta_type ='Org User' id = 'Organizational_User' title = 'Organizational User' def __init__(self, user, email): self.user = user self.email = email getOrgUserDirectory().addUser(self) def getUserName(self): return self.user.getUserName() def addOrgUser(name, password, confirm, email, namespace, REQUEST=None ) : "To be called from dtml. Use _ for namespace" [code omitted--I couldn't figure out how to call it, and it seems not to be active] # class method for OrgUserDirectory _my_Dir = None def getOrgUserDirectory(): "Return the root directory for OrgUsers" global _my_Dir if not _my_Dir : import pdb pdb.set_trace() conn = Zope.app()._p_jar root = conn.root() _my_Dir = root.get("OrgUser", None) if _my_Dir : print "Found directory" else: print "Creating directory" root["OrgUser"] = OrgUserDirectory() _my_Dir = root["OrgUser"] return _my_Dir class OrgUserDirectory(Persistence.PersistentMapping): def __init__(self) : print "Creating OrgUserDirectory" Persistence.PersistentMapping.__init__(self) def addUser(self, orgUser): "Add indicated user to database" name = orgUser.getUserName() if self.has_key(name) : raise "You can not add an existing user" self[name] = orgUser class OrgUserFolder(UserFolder): """Base class for UserFolder-like objects""" meta_type='Org User Folder' title ='Organizational User Folder' manage_userInfo=HTMLFile('editUser',globals()) def addOrgUser(acl, name, password, confirm, email, REQUEST=None ) : "To be called from dtml. " print "passing bound addOrgUser" roles = [] # to be decided domains = [] result = acl._addUser(name, password, confirm, roles, domains) #I think that if we don't pass request, it returns None if all well if result : return result # probably not right since management user = acl.getUser(name) orgUser = OrgUser(user, email) return "I think we're done" def manage_addUserFolder(self,dtself=None,REQUEST=None,**ignored): """ """ f=OrgUserFolder() self=self.this() try: self._setObject('acl_users', f) except: return MessageDialog( title ='Item Exists', message='This object already contains a User Folder', action ='%s/manage_main' % REQUEST['URL1']) self.__allow_groups__=f if REQUEST: return self.manage_main(self,REQUEST,update_menu=1) At 08:58 AM 1/17/00 -0500, Jim Fulton wrote:
Ross Boylan wrote:
Can anyone suggest how to avoid the following? Feel free to consider this a bug report, if it is a bug.
2000-01-16T04:38:30 PANIC(300) ZODB A storage error occurred in the last phase o f a two-phase commit. This shouldn't happen. The application may be in a hosed state, so we will not allow transactions to commit from here on
Was some sort of traceback displayed to go with this? The only time I've seen this is when running out of space.
This happens after some seemingly successful database activity. I believe the error is triggered by the commit before returning to the browser. I suspect I have opened a connection in a way that conflicts with the existing one.
I say, in some code which a form calls, conn = Globals.DB.open() root = conn.root() _my_Dir = root.get("OrgUser", None) if _my_Dir : print "Found directory" else: print "Creating directory" root["OrgUser"] = OrgUserDirectory() #subclass of PersistentMapping _my_Dir = root["OrgUser"] I then add an object to _my_dir, using dictionary protocols.
This is incomplete. I see nothing so far to indicate a problem, but I don't see what else you've done. Why do you open a new connection? If you just want to get the root object, you can get the root object for the connection of some existing persistent object with:
anExistingPersistentObject._p_jar.root()
The attribute '_p_jar' is the database connection for a persistent object.
If you open a new connection, you need to make sure you close it.
The zope session is started with -D. running Zope 2.1.1 on win32.
It may also be relevant that my function returns a plain string to the browser.
Nah.
Jim
-- Jim Fulton mailto:jim@digicool.com Python Powered! Technical Director (888) 344-4332 http://www.python.org Digital Creations http://www.digicool.com http://www.zope.org
Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email address may not be added to any commercial mail list with out my permission. Violation of my privacy with advertising or SPAM will result in a suit for a MINIMUM of $500 damages/incident, $1500 for repeats.