Exemple #1
0
        static void TransactionLoop(Action act, Action onChecked)
        {
            while (true)
            {
                try
                {
                    _context = new TransactionContextInternal();
                    _context.Open();

                    act();

                    if (_rollback.HasValue)
                    {
                        continue;
                    }
                    if (CommitCheck())
                    {
                        onChecked();
                        return;
                    }
                    _context.DoCheckFailed();
                }
                catch (Exception ex) when(IsTransException(ex))
                {
                }
                finally
                {
                    if (_context != null)
                    {
                        _context.DoRollback();
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Runs a transaction, with repetitions if needed, until it passes the commit check,
        /// and then stops. The fields that will be written into, remain locked! It returns
        /// an object which can be used to later commit the transaction, roll it back, or run
        /// code inside of its scope, restricted to fields touched by the original transaction.
        /// Receives a timeout in milliseconds, and the returned continuation will, if not
        /// completed by then, automatically roll back by this time.
        /// </summary>
        public static CommitContinuation RunToCommit(int timeoutMs, Action act)
        {
            if (IsInTransaction)
            {
                throw new InvalidOperationException("Operation not allowed in transaction.");
            }
            CommitContinuation res = null;

            try
            {
                TransactionLoop(act, () => {
                    res      = _context;
                    _context = null;
                });
                return(res);
            }
            finally
            {
                if (res != null && !res.Completed)
                {
                    res.StartTimer(timeoutMs);
                }
            }
        }