Beispiel #1
0
    def run_in_tx(fun, *args, **kwargs):
        context = context_from_method(fun, args, kwargs)
        _context.x = context

        if not _db:
            raise Exception('DB not initalized')

        try:
            transaction.begin()
            _context.x = None

            res = fun(*args, **kwargs)
            if proxy:
                return make_persistent_proxy(res, context)
            return res
        finally:
            transaction.abort()
Beispiel #2
0
    def run_in_tx(fun, *args, **kwargs):
        context = context_from_method(fun, args, kwargs)
        _context.x = context

        if not _db:
            raise Exception('DB not initalized')

        try:
            transaction.begin()
            _context.x = None

            res = fun(*args, **kwargs)
            if proxy:
                return make_persistent_proxy(res, context)
            return res
        finally:
            transaction.abort()
Beispiel #3
0
 def execute(self, args):
     # we obtained `this` before the action exited from the db.transact decorator
     # thus we need to reapply the db proxy
     this.context = make_persistent_proxy(this.context, db.context(self))
     return fun(this, self, args)
Beispiel #4
0
    def run_in_tx(fun, *args, **kwargs):
        if not _db:
            raise Exception('DB not initalized')

        context = context_from_method(fun, args, kwargs)
        _context.x = context

        cfg = get_config()

        def trace(msg, t, force=False):
            ch = '/'
            if msg == "BEGINNING":
                ch = '\\'
            if cfg.getboolean('debug', 'trace_transactions', False) or force:
                trace_fun = log.error
            else:
                trace_fun = log.debug
            trace_fun("%s\ttx:%s %s\tin %s from %s, line %s %s" %
                      (msg, t.description, ch, fun, fun.__module__, inspect.getsourcelines(fun)[1], ch))

        retries = cfg.getint('db', 'conflict_retries')

        retrying = False
        for i in xrange(0, retries + 1):
            try:
                t = transaction.begin()
                t.note("%s" % (random.randint(0, 1000000)))
                trace("BEGIN", t)
                result = fun(*args, **kwargs)
            except RollbackException:
                transaction.abort()
                return
            except:
                trace("ROLLBACK ON ERROR", t)
                transaction.abort()
                raise
            else:
                try:
                    if isinstance(result, RollbackValue):
                        trace("ROLLBACK", t)
                        result = result.value
                        transaction.abort()
                    else:
                        trace("COMMIT", t)
                        transaction.commit()
                        if retrying:
                            trace("Succeeded commit, after %s attempts" % i, t)

                    _context.x = None
                    return make_persistent_proxy(result, context)
                except ReadConflictError as e:
                    trace("GOT READ CONFLICT IN RW TRANSACT, retrying %s" % i, t, force=True)
                    retrying = True
                    time.sleep(random.random() * 0.2)
                except ConflictError as e:
                    trace("GOT WRITE CONFLICT IN RW TRANSACT, retrying %s" % i, t, force=True)
                    retrying = True
                    time.sleep(random.random() * 0.2)
                except StorageTransactionError as e:
                    if e.args and e.args[0] == "Duplicate tpc_begin calls for same transaction":
                        # This may happen when an object attached to one connection is used in anther
                        # connection's transaction. Check and compare _p_jar attributes of all objects
                        # involved in this transaction! They all must be the same.
                        trace("DUPLICATE tpc_begin IN RW TRANSACT", t, force=True)
                    raise
                except:
                    trace('ABORT: bad commit attempt', t)
                    transaction.abort()
                    raise
        raise e
Beispiel #5
0
    def run_in_tx(fun, *args, **kwargs):
        if not _db:
            raise Exception('DB not initalized')

        context = context_from_method(fun, args, kwargs)
        _context.x = context

        cfg = get_config()

        def trace(msg, t, force=False):
            ch = '/'
            if msg == "BEGINNING":
                ch = '\\'
            if cfg.getboolean('debug', 'trace_transactions', False) or force:
                trace_fun = log.error
            else:
                trace_fun = log.debug
            trace_fun("%s\ttx:%s %s\tin %s from %s, line %s %s" %
                      (msg, t.description, ch, fun, fun.__module__, inspect.getsourcelines(fun)[1], ch))

        retries = cfg.getint('db', 'conflict_retries')

        retrying = False
        for i in xrange(0, retries + 1):
            try:
                t = transaction.begin()
                t.note("%s" % (random.randint(0, 1000000)))
                trace("BEGIN", t)
                result = fun(*args, **kwargs)
            except RollbackException:
                transaction.abort()
                return
            except:
                trace("ROLLBACK ON ERROR", t)
                transaction.abort()
                raise
            else:
                try:
                    if isinstance(result, RollbackValue):
                        trace("ROLLBACK", t)
                        result = result.value
                        transaction.abort()
                    else:
                        trace("COMMIT", t)
                        transaction.commit()
                        if retrying:
                            trace("Succeeded commit, after %s attempts" % i, t)

                    _context.x = None
                    return make_persistent_proxy(result, context)
                except ReadConflictError as e:
                    trace("GOT READ CONFLICT IN RW TRANSACT, retrying %s" % i, t, force=True)
                    retrying = True
                    time.sleep(random.random() * 0.2)
                except ConflictError as e:
                    trace("GOT WRITE CONFLICT IN RW TRANSACT, retrying %s" % i, t, force=True)
                    retrying = True
                    time.sleep(random.random() * 0.2)
                except StorageTransactionError as e:
                    if e.args and e.args[0] == "Duplicate tpc_begin calls for same transaction":
                        # This may happen when an object attached to one connection is used in anther
                        # connection's transaction. Check and compare _p_jar attributes of all objects
                        # involved in this transaction! They all must be the same.
                        trace("DUPLICATE tpc_begin IN RW TRANSACT", t, force=True)
                    raise
                except:
                    trace('ABORT: bad commit attempt', t)
                    transaction.abort()
                    raise
        raise e