# mostly from JP
# added the functionality to run synchronious if there is already a active
# transaction
def _transact( engine ):
"""
return a high level function bind to a particulary
sqlalchemy engine
this function is suitable to use as a decorator
a decorated function returns a Deferred while its body
is running in a separate thread
"""
def _transaction( f ):
# _transaction *is* the decorator
def _wrap(*args, **kwargs):
def _1():
# either method works here now;
# either contextual_connect()/begin()/trans.commit()
# or engine.begin()/commit()
conn = meta.engine.contextual_connect()
trans = conn.begin()
try:
r = f(*args, **kwargs)
except:
trans.rollback()
conn.close()
raise
else:
trans.commit()
conn.close()
return r
if isInIOThread( ):
return threads.deferToThread(_1)
else:
return _1( )
_wrap.__name__ = f.__name__
return _wrap
return _transaction
transact = _transact( meta )