# 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 )