.NET Core +弹性事务处理+ SqlBulkCopy,发生“意外的现有事务”异常

时间:2018-07-13 01:49:55

标签: .net-core azure-sql-database

我正在使用.NET Core 2.1.2。

我将SQL数据库用于数据库并运行以下代码,第二个sqlbulk.WriteToServer引发“意外的现有事务”异常。

using System;
using System.Data;
using System.Data.SqlClient;
using System.Transactions;

namespace sqldb
{
    class Program
    {
        static void Main(string[] args)
        {
            var constr = new SqlConnectionStringBuilder(){
                DataSource = "xxxxxxxx.database.windows.net",
                UserID = "xxxxxxx",
                Password = "xxxxxx"
            };
            using (var scope = new TransactionScope()){
                constr.InitialCatalog = "DB1";
                var dtable = new System.Data.DataTable();
                dtable.TableName = "T1";
                dtable.Columns.Add("C1");
                var drow = dtable.NewRow();
                drow["C1"] = 1;
                dtable.Rows.Add(drow);

                using (var con = new SqlConnection(constr.ToString())){
                    con.Open();
                    var sqlbulk = new System.Data.SqlClient.SqlBulkCopy(con);
                    sqlbulk.DestinationTableName = "T1";
                    sqlbulk.WriteToServer(dtable);
                }

                constr.InitialCatalog = "DB2";
                using (var con = new SqlConnection(constr.ToString())){
                    con.Open();
                    var sqlbulk = new System.Data.SqlClient.SqlBulkCopy(con);
                    sqlbulk.DestinationTableName = "T1";
                    sqlbulk.WriteToServer(dtable);
                }
                scope.Complete();
            }
        }
    }
}

我在每个数据库上执行以下查询,并确认Elastic Transaction的状态,它已注册为DTC。

SELECT * FROM sys.dm_tran_active_transactions 

在Transaction Scope中,将带有sqlbulkcopy的数据插入到SQL数据库的多个DB中似乎会导致错误,但是有一些解决方法吗? (在Transaction Scope中,为同一个数据库插入具有多个SqlBulkCopy的数据/为多个数据库进行简单插入可以正常工作)

1 个答案:

答案 0 :(得分:0)

看起来SqlBulkCopy与System.Transactions混淆了。使用已经在System.Transactions.Transaction中登记的SqlConnection,您可以使用SqlConnection.BeginTransaction启动“嵌套”事务,然后将 that 事务传递给SqlBulkCopy。 EG

            using (var con = new SqlConnection(constr.ToString()))
            {
                con.Open();

                using (var tran = con.BeginTransaction())
                {
                    var options = new SqlBulkCopyOptions();                        
                    var sqlbulk = new SqlBulkCopy(con,options,tran);

                    sqlbulk.DestinationTableName = "T1";
                    sqlbulk.WriteToServer(dtable);
                    tran.Commit();
                }
            }