我正尝试在对不同 SQL Server 实例的两个查询中使用 TransactionScope(事务被提升为 MSDTC)。我让它在不使用 Tasks 的情况下同步工作,但在异步使用 Tasks 时无法使事务回滚。
我已经隐藏了服务器的连接字符串和更新语句,但请放心,它们都可以毫无问题地连接和执行 SQL。我有意将方法 runTwo()
中的 SQL 设置为失败并引发异常。
我正在使用 .Net 4.5.2,其中包括枚举 TransactionScopeAsyncFlowOption.Enabled
(在 TransactionScope 构造函数中),我认为它应该处理跨线程的事务,但我无法让它工作。
static void Main()
{
List<Task> tasks = new List<Task>();
using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
try
{
tasks.Add(Task.Run(() => runOne()));
tasks.Add(Task.Run(() => runTwo()));
Task.WhenAll(tasks);
//Complete the scope
scope.Complete();
}
catch (Exception)
{
Transaction.Current.Rollback();
}
}
Console.ReadLine();
}
private static void runOne()
{
//Get the base SQL connection
using (SqlConnection conn = new SqlConnection("Data Source=SERVER1....."))
{
conn.Open();
SqlCommand command1 = new SqlCommand
{
CommandText = "Update .. Complete Successfully",
CommandType = CommandType.Text,
Connection = conn
};
command1.ExecuteNonQuery();
}
}
private static void runTwo()
{
using (
SqlConnection conn =
new SqlConnection("Data Source=SERVER2...")
)
{
conn.Open();
SqlCommand command2 = new SqlCommand
{
CommandText = "Update .... Raises Exception",
CommandType = CommandType.Text,
Connection = conn
};
//Execute the command
command2.ExecuteNonQuery();
}
}
最佳答案
这个:
Task.WhenAll(tasks);
是你的问题。 Task.WhenAll
返回一个 awaitable,它不会阻塞 方法调用。由于您使用的是无法等待的控制台应用程序,因此您必须推迟使用 Task.WaitAll
而不是它会显式阻塞,直到两个请求都完成并通过 AggregateException 传播任何异常
try
{
Task.WaitAll(new[] { Task.Run(() => runOne()),
Task.Run(() => runTwo()) });
scope.Complete();
}
关于c# - 无法将 TransactionScope 与任务一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28065644/