TransactionScope Class 事务的使用
TransactionScope
错误的理解就是Complete()方法是提交事务的,事实上,它的作用的表示本事务完成,它一般放在try{}的结尾处,不用判断前台操作是否成功,如果不成功,它会自己回滚。
在实例化TransactionScope通过new语句,事务管理器确定哪些事务参与进来。 一旦确定,该范围将始终参与该事务。 此决策基于两个因素:是否存在环境事务以及构造函数中 TransactionScopeOption 参数的值。 环境事务是在代码中执行的事务。 可通过调用 Transaction.Current 类的静态 Transaction 属性,获取对环境事务的引用。 有关如何使用此参数的详细信息,请参阅的"事务流管理"部分实现隐式 Transaction Using Transaction Scope主题。
如果事务范围内未不发生任何异常 (即之间的初始化TransactionScope对象并调用其Dispose方法),则的事务范围所参与的允许才能继续。 如果异常确实发生事务范围内,参与到其中的事务将回滚。
你的应用程序完成所有工作时它想要在事务中执行,应调用Complete方法一次,从而通知该事务管理器是可接受提交事务。 未能调用此方法中止事务。
调用Dispose方法标记的事务范围的末尾。 在调用此方法之后所发生的异常不会影响事务。
如果您修改的值Current的作用域,将引发异常时Dispose调用。 但是,在作用域结束时,以前的值将恢复。 此外,如果您调用Dispose上Current创建了事务的事务作用域,在事务中止的作用域的末尾。
msdn:TransactionScope Class (System.Transactions) | Microsoft Docs
https://docs.microsoft.com/zh-cn/dotnet/api/system.transactions.transactionscope?redirectedfrom=MSDN&view=netframework-4.7.2
示例
//此函数接受2个连接字符串和命令的参数,以创建涉及两个SQL服务器的事务。如果事务已提交,则返回值>0;如果事务回滚,则返回值0。
//要测试此代码,可以通过更改连接字符串连接到同一服务器上的两个不同数据库,或者通过更改Connection2代码块中的代码连接到另一个
//第三方RDBMS。
static public int CreateTransactionScope(string connectString1, string connectString2,string commandText1, string commandText2)
{
// 将返回值初始化为零并创建一个StringWriter来显示结果。
int returnValue = 0;
System.IO.StringWriter writer = new System.IO.StringWriter();
try
{
// 创建TransactionScope以执行命令,确保这两个命令都可以作为单个工作单元提交或回滚。
using (TransactionScope scope = new TransactionScope())
{
using (SqlConnection connection1 = new SqlConnection(connectString1))
{
// 打开连接会自动将其作为轻型事务登记到TransactionScope中。
connection1.Open();
// 创建sqlcommand对象并执行第一个命令。
SqlCommand command1 = new SqlCommand(commandText1, connection1);
returnValue = command1.ExecuteNonQuery();
writer.WriteLine("Rows to be affected by command1: {0}", returnValue);
// 如果你到了这里,这意味着command1成功了。通过将connection2的using块嵌套在connection1的using块中,
//可以节省服务器和网络资源,因为只有在事务可以提交时,才会打开connection2。
using (SqlConnection connection2 = new SqlConnection(connectString2))
{
// 当连接2打开时,事务将升级为完全分布式事务。
connection2.Open();
// 在第二个数据库中执行第二个命令。
returnValue = 0;
SqlCommand command2 = new SqlCommand(commandText2, connection2);
returnValue = command2.ExecuteNonQuery();
writer.WriteLine("Rows to be affected by command2: {0}", returnValue);
}
}
// 完成方法提交事务。如果抛出了异常,则不调用Complete,事务将回滚。
scope.Complete();
}
}
catch (TransactionAbortedException ex)
{
writer.WriteLine("TransactionAbortedException Message: {0}", ex.Message);
}
// 显示消息。
Console.WriteLine(writer.ToString());
return returnValue;
}