我正在阅读C#中的事务范围,它的工作原理如下:
using (connectionDb)
{
connectionDb.Open();
using (var ts = new System.Transactions.TransactionScope())
{ <--
try
{
connectionDb.ExecuteNonQuery();
ts.Complete();
}
catch (Exception)
{
throw;
}
finally
{ }
} <--
}
using括号中的每个子句都在同一个事务中工作,但我不明白代码如何识别数据库命令在作用域上运行而不传递事务作用域参数既不是连接的开放,也不是执行查询。
例如,如果我有以下代码:
var myObject = new MyObject();
var childObject = new ChildObject();
childObject.Foo(myObject);
childObject.Bar(myObject);
我可以为变量myObject
创建一个范围并使用到childObject方法而不通过参数传递吗?像这样:
using(var myObject = new MyObject())
{
childObject.Foo(); -- Here the method use the variable myObject
childObject.Bar(); -- Here the method use the variable myObject
}
答案 0 :(得分:7)
创建TransactionScope时,它存储在静态变量Transaction.Current中,该变量保存在线程本地存储中。与事务交互的方法会查看此变量以确定它们所处的事务。这称为环境事务。
答案 1 :(得分:1)
您的示例显示了环境事务。在引擎盖下,数据库连接检测到您已启动事务并将进入该事务。更多进程可以登记到该事务(例如,MSMQ事务性消息传递),因此当满足将触发回滚的条件时,每个其他登记的进程都可以启动回滚。根据您选择的隔离级别,它还会对数据应用更具侵略性的锁定。1
您的第二位代码将范围您定义的对象,但用例不同。你还是要做这样的事情:
using(var myObject = new MyObject())
{
childObject.Foo(myObject); -- Here the method use the variable myObject
childObject.Bar(myObject); -- Here the method use the variable myObject
}
这给你的是终身管理和样板代码的减少,例如不必手动调用dispose,这种东西。