Ejemplo n.º 1
0
        public async Task Execute(DTOperationRecord record, Func <Task> action)
        {
            try
            {
                await using (DBTransactionScope scope = new DBTransactionScope(System.Transactions.TransactionScopeOption.Required, new System.Transactions.TransactionOptions()
                {
                    IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted, Timeout = new TimeSpan(0, 0, 10)
                }))
                {
                    await _dtOperationRecordStore.UpdateVersion(record.StoreGroupName, record.HashInfo, record.ID, Guid.NewGuid().ToString());

                    await action();

                    await _dtOperationRecordStore.UpdateStatus(record.StoreGroupName, record.HashInfo, record.ID, (int)DTOperationRecordStatus.Complete);

                    scope.Complete();
                }
            }
            catch
            {
                var nRecord = await _dtOperationRecordStore.QueryByID(record.StoreGroupName, record.HashInfo, record.ID);

                if (nRecord != null)
                {
                    await nRecord.Cancel();
                }
                throw;
            }
        }
Ejemplo n.º 2
0
        public async Task Cancel(DTOperationData data)
        {
            if (data.Status == (int)DTOperationDataStatus.Cancel)
            {
                return;
            }
            var service = getService(data.Type);

            await using (DBTransactionScope transactionScope = new DBTransactionScope(TransactionScopeOption.Required, new TransactionOptions()
            {
                IsolationLevel = IsolationLevel.ReadCommitted, Timeout = new TimeSpan(0, 30, 0)
            }))
            {
                await service.Cancel(data.Data);

                var updateResult = await _dtOperationDataStore.UpdateStatus(data.StoreGroupName, data.HashInfo, data.ID, data.Version, (int)DTOperationDataStatus.Cancel);

                if (!updateResult)
                {
                    var fragment = new TextFragment()
                    {
                        Code = TextCodes.DTOperationDataConcurrenceErrorInCancel,
                        DefaultFormatting = "分布式操作数据在Cancel时发生并发错误,StoreGroupName:{0},HashInfo:{1}",
                        ReplaceParameters = new List <object>()
                        {
                            data.StoreGroupName, data.HashInfo, data.ID.ToString()
                        }
                    };

                    throw new UtilityException((int)Errors.DTOperationDataConcurrenceErrorInCancel, fragment);
                }

                transactionScope.Complete();
            }
        }
Ejemplo n.º 3
0
        public DBTransactionScope(TransactionScopeOption scopeOption, TransactionOptions transactionOptions, Action rollbackAction = null)
        {
            _preTransactionScope    = _transactionScope.Value;
            _transactionScope.Value = this;

            _rollbackAction = rollbackAction;

            _preConnections     = _connections.Value;
            _preTransactionInfo = _transactionInfo.Value;

            _transactionInfo.Value = new TransactionInfo()
            {
                ID = Guid.NewGuid(), ScopeOption = scopeOption, TransactionOptions = transactionOptions
            };
            _id                 = _transactionInfo.Value.ID;
            _scopeOption        = _transactionInfo.Value.ScopeOption;
            _transactionOptions = _transactionInfo.Value.TransactionOptions;



            if (_preTransactionInfo == null)
            {
                _needCreateNewTransaction = true;
            }
            else
            {
                if (_preTransactionInfo.TransactionOptions.IsolationLevel != transactionOptions.IsolationLevel)
                {
                    _needCreateNewTransaction = true;
                }
                else
                {
                    _needCreateNewTransaction = false;
                }
            }

            if (!_inTransaction.Value)
            {
                _needClearTransactionScope = true;
            }

            _inTransaction.Value = true;

            //如果是范围是新事务或者忽略,则_needClose=true
            if (scopeOption == TransactionScopeOption.RequiresNew || scopeOption == TransactionScopeOption.Suppress)
            {
                _needClose         = true;
                _connections.Value = new Dictionary <string, DBConnectionContainer>();
                if (scopeOption == TransactionScopeOption.Suppress)
                {
                    _inTransaction.Value = false;
                }
            }
            else if (scopeOption == TransactionScopeOption.Required && _preConnections == null)
            {
                //如果是Required,并且_preConnections为空,则_needClose=true
                _connections.Value = new Dictionary <string, DBConnectionContainer>();
                _needClose         = true;
            }
            else
            {
                if (_connections.Value == null)
                {
                    _connections.Value = new Dictionary <string, DBConnectionContainer>();
                }
                _needClose = false;
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// SQL事务处理封装
        /// </summary>
        /// <param name="isOnlyRead">是否是只读</param>
        /// <param name="isInnerTranaction">当不在事务环境中时,是否需要开启事务</param>
        /// <param name="strConn">连接字符串</param>
        /// <param name="callBack">处理回调函数</param>
        public static async Task SqlTransactionWorkAsync(string dbType, bool isOnlyRead, bool isInnerTranaction, string strConn, Func <DbConnection, DbTransaction, Task> callBack, System.Transactions.IsolationLevel innerTransactionIsolationLevel = System.Transactions.IsolationLevel.ReadCommitted)
        {
            if (!_dbConnGenerates.TryGetValue(dbType, out IDBConnGenerate dbConnGenerate))
            {
                throw new Exception($"not found {dbType} in DBTransactionHelper.DBConnGenerates");
            }

            DbConnection  conn        = null;
            DbTransaction transaction = null;

            //如果当前处于事务环境中
            if (DBTransactionScope.InScope())
            {
                //检查是否已经在事务中创建过连接
                if (DBTransactionScope.CurrentConnections.ContainsKey(strConn.ToLower()) && (DBTransactionScope.CurrentConnections[strConn.ToLower()].Connection.State == ConnectionState.Connecting || DBTransactionScope.CurrentConnections[strConn.ToLower()].Connection.State == ConnectionState.Open))
                {
                    conn        = DBTransactionScope.CurrentConnections[strConn.ToLower()].Connection;
                    transaction = await DBTransactionScope.CurrentConnections[strConn.ToLower()].CreateTransactionAsync(async(connection, options) =>
                    {
                        return(await CreateTransactionAsync(dbConnGenerate, connection, options));
                    });

                    await callBack(conn, transaction);
                }
                else
                {
                    //只读连接在事务中的时候需要做隔离,防止提升到分布式事务
                    if (isOnlyRead)
                    {
                        //using (var transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled))
                        //{
                        await using (conn = dbConnGenerate.Generate(strConn))
                        {
                            await conn.OpenAsync();

                            //判断IsolationLevel是否是ReadUncommitted,如果是,则需要单独创建事务
                            if (DBTransactionScope.CurrentTransactionInfo.TransactionOptions.IsolationLevel == System.Transactions.IsolationLevel.ReadUncommitted)
                            {
                                transaction = await dbConnGenerate.GenerateTransactionAsync(conn, ConvertIsolationLevel(DBTransactionScope.CurrentTransactionInfo.TransactionOptions.IsolationLevel));
                            }
                            else
                            {
                                transaction = null;
                            }
                            await callBack(conn, transaction);

                            if (transaction != null)
                            {
                                await transaction.CommitAsync();
                            }
                            await conn.CloseAsync();
                        }

                        //    transactionScope.Complete();
                        //}
                    }
                    else
                    {
                        //如果是写连接,需要加入到事务连接列表中
                        conn = dbConnGenerate.Generate(strConn);
                        await conn.OpenAsync();

                        DBTransactionScope.CurrentConnections[strConn.ToLower()] = new DBTransactionScope.DBConnectionContainer()
                        {
                            Connection = conn, Error = true
                        };
                        transaction = await DBTransactionScope.CurrentConnections[strConn.ToLower()].CreateTransactionAsync(async(connection, options) =>
                        {
                            return(await CreateTransactionAsync(dbConnGenerate, connection, options));
                        });

                        await callBack(conn, transaction);
                    }
                }
            }
            else
            {
                //不在事务中,需要创建连接,由isInnerTranaction确定是否需要创建事务
                if (isInnerTranaction)
                {
                    //using (var transactionScope = new TransactionScope(TransactionScopeOption.Required, TransactionScopeAsyncFlowOption.Enabled))
                    //{
                    await using (conn = dbConnGenerate.Generate(strConn))
                    {
                        await conn.OpenAsync();

                        transaction = await dbConnGenerate.GenerateTransactionAsync(conn, ConvertIsolationLevel(innerTransactionIsolationLevel));
                        await callBack(conn, transaction);

                        await transaction.CommitAsync();

                        await conn.CloseAsync();
                    }

                    //    transactionScope.Complete();
                    //}
                }
                else
                {
                    await using (conn = dbConnGenerate.Generate(strConn))
                    {
                        await conn.OpenAsync();
                        await callBack(conn, null);

                        await conn.CloseAsync();
                    }
                }
            }
        }