Pet*_*ook 8 .net c# system.transactions
我们正在尝试使用下面的代码.NET 3.5和SQL Server 2005进行间接嵌套事务.
MSDN说,当使用TransactionScope时,只要应用程序在事务中打开第二个连接(甚至是同一个数据库),事务就会升级.
void RootMethod()
{
using(TransactionScope scope = new TransactionScope())
{
/* Perform transactional work here */
FirstMethod();
SecondMethod();
scope.Complete();
}
}
void FirstMethod()
{
using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
using (SqlConnection conn1 = new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI"))
{
string insertString = @"
insert into Categories
(CategoryName, Description)
values ('Laptop1', 'Model001')";
conn1.Open();
SqlCommand cmd = new SqlCommand(insertString, conn1);
cmd.ExecuteNonQuery();
}
scope.Complete();
}
}
void SecondMethod()
{
using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
using (SqlConnection conn2 = new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI"))
{
string insertString = @"
insert into Categories
(CategoryName, Description)
values ('Laptop2', 'Model002')";
conn2.Open(); //Looks like transactionabortedException is happening here
SqlCommand cmd = new SqlCommand(insertString, conn2);
cmd.ExecuteNonQuery();
}
scope.Complete();
}
}
Run Code Online (Sandbox Code Playgroud)
有时候,事务失败了,没有提升到DTC,我们得到以下内部堆栈跟踪,
System.Transactions.TransactionAbortedException: The transaction has aborted. --->
System.Transactions.TransactionPromotionException: Failure while attempting to promote transaction. --->
System.InvalidOperationException: The requested operation cannot be completed because the connection has been broken.
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlDelegatedTransaction.Promote() --- End of inner exception stack trace ---
at System.Data.SqlClient.SqlDelegatedTransaction.Promote()
at System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)
at System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx)
--- End of inner exception stack trace ---
at System.Transactions.TransactionStateAborted.CreateAbortingClone(InternalTransaction tx)
at System.Transactions.DependentTransaction..ctor(IsolationLevel isoLevel, InternalTransaction internalTransaction, Boolean blocking)
at System.Transactions.Transaction.DependentClone(DependentCloneOption cloneOption)
at System.Transactions.TransactionScope.SetCurrent(Transaction newCurrent)
at System.Transactions.TransactionScope.PushScope()
at System.Transactions.TransactionScope..ctor(TransactionScopeOption scopeOption)
Run Code Online (Sandbox Code Playgroud)
有人可以帮我弄清楚这次失败的原因吗?
如果您使用 TransactionScope 并且您:
交易将升级到 DTC。检查另一个 SO 问题:TransactionScope 在某些机器上自动升级到 MSDTC?
解决方案是:
使用 SqlTransaction 而不是 TransactionScope 就像以前的答案所暗示的那样:
using (var conn = new SqlConnection(connectionString))
{
using (var tx = conn.BeginTransaction())
{
FirstMethod(conn);
SecondMethod(conn);
tx.Commit();
}
}
Run Code Online (Sandbox Code Playgroud)小智 0
我可以向您提出更好的方法来实现您的目标。每个连接应该有一个事务用于 2 个数据库调用。
它应该像
using (SqlConnection conn1 = new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI"))
{
using (conn1.BeginTransaction()
{
try
{
FirstMethod(Conn1);
SecondMethod(Conn2);
}
catch()
{
}
}
}
Run Code Online (Sandbox Code Playgroud)