[Zope] Database connectors
Maciej Wisniowski
maciej.wisniowski at coig.katowice.pl
Tue Nov 21 03:56:49 EST 2006
> In fact, the "_v_database_connection" is *NOT* necessary to
> abort(rollback) commit the transaction:
>
I have procedure WYJATEK in Oracle that
simply raises exception.
I've created StoredProcedure in Zope called
'wyjatek' and navigated to 'Test' page.
Then I've restarted Zope, and after restart I've
just hit 'Test' button.
Below is full pdb session (Zope running with one thread only) starting
from :
/opt/Zope/2.8.8/lib/python/transaction/_transaction.py(492)abort()
In short: there are two resource managers registered:
1. <Connection at b62f228c>
2. <MultiObjectResourceAdapter for <Procedure at wyjatek> at -1241707860>
When 1. is aborted, then in it's _abort method I have:
self._registered_objects == [<Procedure at wyjatek>]
and the code below is executed:
for obj in self._registered_objects:
oid = obj._p_oid
(...)
self._cache.invalidate(oid)
Later, 2. is being aborted and in SP.py _abort I have:
self._v_db.db.rollback()
AttributeError: '_v_db'
So there is no rollback to Oracle.
SP.py __call__ is:
self._register() # uses:
transaction.get().register(Surrogate(self))
try:
# Note, this does not do result promotion like the DA query will
# which is probably bad. OracleDates in particular look like
# DateTimes but arent at all the same!
results = apply ( self._v_proc, args, kw )
return results
#return self._lobConvert(results)
except:
logger.error('Error in dco2 procedure')
self._v_proc = None
raise # Reraise error
Is this because of: self._cache.invalidate(oid)?
Maciej Wisniowski
Full pdb session:
2006-11-21 08:04:16 INFO Zope Ready to handle requests
2006-11-21 08:04:16 DEBUG txn.16386 new transaction
2006-11-21 08:04:16 INFO _transaction abort
2006-11-21 08:04:16 INFO _transaction []
(...)
2006-11-21 08:04:24 DEBUG txn.16386 new transaction
2006-11-21 08:04:24 DEBUG DCOracle2 - DCOracle2.py Created new DCO2
connection <Products.DCOracle2.DCOracle2.DCOracle2.connection instance
at 0xb5fd0dac>
2006-11-21 08:04:24 ERROR DCOracle2 - SP.py Error in dco2 procedure
2006-11-21 08:04:24 ERROR Zope.SiteErrorLog
http://eurolinux:8091/testOracleDRTest/wyjatek/manage_testZOracleStoredProcedure
Traceback (most recent call last):
File "/opt/Zope/2.8.8/lib/python/ZPublisher/Publish.py", line 114, in
publish
request, bind=1)
File "/opt/Zope/2.8.8/lib/python/ZPublisher/mapply.py", line 88, in mapply
if debug is not None: return debug(object,args,context)
File "/opt/Zope/2.8.8/lib/python/ZPublisher/Publish.py", line 40, in
call_object
result=apply(object,args) # Type s<cr> to step into published object.
File "/opt/Zope/instancje/oracletest288/Products/DCOracle2/SP.py",
line 341, in manage_testZOracleStoredProcedure
v = apply(self,[],REQUEST.form)
File "/opt/Zope/instancje/oracletest288/Products/DCOracle2/SP.py",
line 312, in __call__
results = apply(self._v_proc,args,kw)
File
"/opt/Zope/instancje/oracletest/Products/DCOracle2/DCOracle2/DCOracle2.py",
line 1563, in __call__
cursor.execute(sql,__plist=args)
File
"/opt/Zope/instancje/oracletest/Products/DCOracle2/DCOracle2/DCOracle2.py",
line 1023, in execute
result = self._cursor.execute()
DatabaseError: (20001, 'ORA-20001: BlaBlaBla\nORA-06512: at
"TEST.WYJATEKFUNC", line 6\nORA-06512: at line 1')
2006-11-21 08:04:24 INFO _transaction abort
2006-11-21 08:04:24 INFO _transaction [<Connection at b62f228c>,
<MultiObjectResourceAdapter for <Procedure at wyjatek> at -1241707860>]
--Return--
> /usr/local/lib/python2.3/pdb.py(992)set_trace()->None
-> Pdb().set_trace()
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(492)abort()
-> for rm in self._resources:
(Pdb) l
487 self._synchronizers.map(lambda s: s.beforeCompletion(self))
488
489 tb = None
490 logger.info(str(self._resources))
491 import pdb;pdb.set_trace()
492 -> for rm in self._resources:
493 try:
494 rm.abort(self)
495 except:
496 if tb is None:
497 t, v, tb = sys.exc_info()
(Pdb) p self._resources
[<Connection at b62f228c>, <MultiObjectResourceAdapter for <Procedure at
wyjatek> at -1241707860>]
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(493)abort()
-> try:
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(494)abort()
-> rm.abort(self)
(Pdb) s
--Call--
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(338)abort()
-> def abort(self, transaction):
(Pdb) l
333
##########################################################################
334
335
##########################################################################
336 # Data manager (ISavepointDataManager) methods
337
338 -> def abort(self, transaction):
339 """Abort a transaction and forget all changes."""
340
341 # The order is important here. We want to abort registered
342 # objects before we process the cache. Otherwise, we
may un-add
343 # objects added in savepoints. If they've been modified
since
(Pdb) n
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(348)abort()
-> self._abort()
(Pdb) l
343 # objects added in savepoints. If they've been modified
since
344 # the savepoint, then they won't have _p_oid or _p_jar after
345 # they've been unadded. This will make the code in _abort
346 # confused.
347
348 -> self._abort()
349
350 if self._savepoint_storage is not None:
351 self._abort_savepoint()
352
353 self._tpc_cleanup()
(Pdb) s
--Call--
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(355)_abort()
-> def _abort(self):
(Pdb) n
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(358)_abort()
-> for obj in self._registered_objects:
(Pdb) l
353 self._tpc_cleanup()
354
355 def _abort(self):
356 """Abort a transaction and forget all changes."""
357
358 -> for obj in self._registered_objects:
359 oid = obj._p_oid
360 assert oid is not None
361 if oid in self._added:
362 del self._added[oid]
363 del obj._p_jar
(Pdb) p self._registered_objects
[<Procedure at wyjatek>]
(Pdb) n
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(359)_abort()
-> oid = obj._p_oid
(Pdb) n
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(360)_abort()
-> assert oid is not None
(Pdb) n
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(361)_abort()
-> if oid in self._added:
(Pdb) p self._added
{}
(Pdb) l
356 """Abort a transaction and forget all changes."""
357
358 for obj in self._registered_objects:
359 oid = obj._p_oid
360 assert oid is not None
361 -> if oid in self._added:
362 del self._added[oid]
363 del obj._p_jar
364 del obj._p_oid
365 else:
366
(Pdb) n
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(386)_abort()
-> self._cache.invalidate(oid)
(Pdb) l
381 # go ahead and invalidate now. Fortunately, it's
382 # pretty unlikely that the object we are
invalidating
383 # was invalidated by another thread, so the risk
of a
384 # reread is pretty low.
385
386 -> self._cache.invalidate(oid)
387
388 def _tpc_cleanup(self):
389 """Performs cleanup operations to support tpc_finish and
tpc_abort."""
390 self._conflicts.clear()
391 if not self._synch:
(Pdb) s
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(358)_abort()
-> for obj in self._registered_objects:
(Pdb) n
--Return--
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(358)_abort()->None
-> for obj in self._registered_objects:
(Pdb) n
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(350)abort()
-> if self._savepoint_storage is not None:
(Pdb) l
345 # they've been unadded. This will make the code in _abort
346 # confused.
347
348 self._abort()
349
350 -> if self._savepoint_storage is not None:
351 self._abort_savepoint()
352
353 self._tpc_cleanup()
354
355 def _abort(self):
(Pdb) n
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(353)abort()
-> self._tpc_cleanup()
(Pdb) s
--Call--
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(388)_tpc_cleanup()
-> def _tpc_cleanup(self):
(Pdb) n
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(390)_tpc_cleanup()
-> self._conflicts.clear()
(Pdb) l
385
386 self._cache.invalidate(oid)
387
388 def _tpc_cleanup(self):
389 """Performs cleanup operations to support tpc_finish and
tpc_abort."""
390 -> self._conflicts.clear()
391 if not self._synch:
392 self._flush_invalidations()
393 self._needs_to_join = True
394 self._registered_objects = []
395
(Pdb) n
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(391)_tpc_cleanup()
-> if not self._synch:
(Pdb) n
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(393)_tpc_cleanup()
-> self._needs_to_join = True
(Pdb) n
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(394)_tpc_cleanup()
-> self._registered_objects = []
(Pdb) n
--Return--
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(394)_tpc_cleanup()->None
-> self._registered_objects = []
(Pdb) n
--Return--
> /opt/Zope/2.8.8/lib/python/ZODB/Connection.py(353)abort()->None
-> self._tpc_cleanup()
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(492)abort()
-> for rm in self._resources:
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(493)abort()
-> try:
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(494)abort()
-> rm.abort(self)
(Pdb) p rm
<MultiObjectResourceAdapter for <Procedure at wyjatek> at -1241707860>
(Pdb) s
--Call--
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(563)abort()
-> def abort(self, txn):
(Pdb) l
558 self.ncommitted += 1
559
560 def tpc_vote(self, txn):
561 self.manager.tpc_vote(txn)
562
563 -> def abort(self, txn):
564 tb = None
565 for o in self.objects:
566 try:
567 self.manager.abort(o, txn)
568 except:
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(564)abort()
-> tb = None
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(565)abort()
-> for o in self.objects:
(Pdb) p self.objects
[<Shared.DC.ZRDB.TM.Surrogate instance at 0xb5fd0c6c>]
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(566)abort()
-> try:
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(567)abort()
-> self.manager.abort(o, txn)
(Pdb) s
--Call--
> /opt/Zope/instancje/oracletest288/Products/DCOracle2/SP.py(158)abort()
-> def abort(self, *ignored):
(Pdb) l
153
154 if self._v_finalize:
155 try: self._finish()
156 finally: self._v_registered=0
157
158 -> def abort(self, *ignored):
159 try: self._abort()
160 finally: self._v_registered=0
161
162 tpc_abort = abort
163
(Pdb) p self._v_db
*** AttributeError: <exceptions.AttributeError instance at 0xb5fd09ec>
(Pdb) n
> /opt/Zope/instancje/oracletest288/Products/DCOracle2/SP.py(159)abort()
-> try: self._abort()
(Pdb) s
--Call--
> /opt/Zope/instancje/oracletest288/Products/DCOracle2/SP.py(219)_abort()
-> def _abort(self, *ignored):
(Pdb) l
214 self._v_db.db.commit()
215 except Exception, e:
216 logger.error( 'Exception in SP.py, _finish: %s' % (e) )
217 print 'Exception in SP.py, _finish: %s' % (e)
218
219 -> def _abort(self, *ignored):
220 try:
221 logger.info('_abort')
222 self._v_db.db.rollback()
223 except Exception, e:
224 logger.error( 'Exception in SP.py, _abort: %s' % (e) )
(Pdb) p self._v_db
*** AttributeError: <exceptions.AttributeError instance at 0xb603988c>
(Pdb) n
> /opt/Zope/instancje/oracletest288/Products/DCOracle2/SP.py(220)_abort()
-> try:
(Pdb) n
> /opt/Zope/instancje/oracletest288/Products/DCOracle2/SP.py(221)_abort()
-> logger.info('_abort')
(Pdb) n
2006-11-21 08:08:18 INFO DCOracle2 - SP.py _abort
> /opt/Zope/instancje/oracletest288/Products/DCOracle2/SP.py(222)_abort()
-> self._v_db.db.rollback()
(Pdb) n
AttributeError: '_v_db'
> /opt/Zope/instancje/oracletest288/Products/DCOracle2/SP.py(222)_abort()
-> self._v_db.db.rollback()
(Pdb) l
217 print 'Exception in SP.py, _finish: %s' % (e)
218
219 def _abort(self, *ignored):
220 try:
221 logger.info('_abort')
222 -> self._v_db.db.rollback()
223 except Exception, e:
224 logger.error( 'Exception in SP.py, _abort: %s' % (e) )
225
226 def description(self):
227 if getattr(self,"_v_proc",None) is None: self._connect()
(Pdb) n
> /opt/Zope/instancje/oracletest288/Products/DCOracle2/SP.py(223)_abort()
-> except Exception, e:
(Pdb) n
> /opt/Zope/instancje/oracletest288/Products/DCOracle2/SP.py(224)_abort()
-> logger.error( 'Exception in SP.py, _abort: %s' % (e) )
(Pdb) n
2006-11-21 08:08:52 ERROR DCOracle2 - SP.py Exception in SP.py, _abort:
_v_db
--Return--
>
/opt/Zope/instancje/oracletest288/Products/DCOracle2/SP.py(224)_abort()->None
-> logger.error( 'Exception in SP.py, _abort: %s' % (e) )
(Pdb) n
> /opt/Zope/instancje/oracletest288/Products/DCOracle2/SP.py(160)abort()
-> finally: self._v_registered=0
(Pdb) n
--Return--
>
/opt/Zope/instancje/oracletest288/Products/DCOracle2/SP.py(160)abort()->None
-> finally: self._v_registered=0
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(565)abort()
-> for o in self.objects:
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(575)abort()
-> if tb is not None:
(Pdb) n
--Return--
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(575)abort()->None
-> if tb is not None:
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(492)abort()
-> for rm in self._resources:
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(501)abort()
-> if self._manager:
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(502)abort()
-> self._manager.free(self)
(Pdb) l
497 t, v, tb = sys.exc_info()
498 self.log.error("Failed to abort resource
manager: %s",
499 rm, exc_info=sys.exc_info())
500
501 if self._manager:
502 -> self._manager.free(self)
503
504 self._synchronizers.map(lambda s: s.afterCompletion(self))
505
506 self.log.debug("abort")
507
(Pdb) p self._manager
<transaction._manager.ThreadTransactionManager object at 0xb715aaec>
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(504)abort()
-> self._synchronizers.map(lambda s: s.afterCompletion(self))
(Pdb) n
> /opt/Zope/2.8.8/lib/python/transaction/_transaction.py(506)abort()
-> self.log.debug("abort")
(Pdb) c
2006-11-21 08:09:33 DEBUG txn.16386 abort
2006-11-21 08:09:33 DEBUG txn.16386 new transaction
2006-11-21 08:09:33 INFO _transaction abort
2006-11-21 08:09:33 INFO _transaction []
--Return--
> /usr/local/lib/python2.3/pdb.py(992)set_trace()->None
-> Pdb().set_trace()
More information about the Zope
mailing list