Rob*_*ner 27 .net transactions transactionscope
我试图嵌套TransactionScopes(.net 4.0),就像在SQL Server中嵌套事务一样,但看起来它们的运行方式不同.我希望我的子事务能够在它们失败时回滚,但允许父事务决定是否提交/回滚整个操作.问题是当第一次完成时,事务被回滚.我意识到完全不同于提交.
我正在尝试做的一个非常简化的例子:
static void Main(string[] args)
{
using(var scope = new TransactionScope()) // Trn A
{
// Insert Data A
DoWork(true);
DoWork(false);
// Rollback or Commit
}
}
// This class is a few layers down
static void DoWork(bool fail)
{
using(var scope = new TransactionScope()) // Trn B
{
// Update Data A
if(!fail)
{
scope.Complete();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我不能使用Suppress或RequiresNew选项,因为Trn B依赖于Trn A插入的数据.如果我确实使用这些选项,Trn B被Trn A阻止.
任何想法如何让它工作,或甚至可能使用System.Transactions命名空间?
谢谢
Aar*_*ght 48
你可能不会喜欢这个答案,但......
在嵌套范围内投票
虽然嵌套作用域可以加入根作用域的环境事务,但在嵌套作用域中调用Complete不会影响根作用域.仅当从根范围到最后一个嵌套范围的所有范围都投票提交事务时,才会提交事务.
(来自使用事务范围实现隐式事务)
TransactionScope遗憾的是,该课程没有提供任何机制(我知道)用于隔离工作单元.这是全有或全无.您可以通过使用来阻止在特定工作单元上发生任何事务TransactionScopeOption.Suppress,但这可能不是您想要的,因为您将失去该范围内的任何内容的原子性.
使用a时只有一个"环境"事务TransactionScope.一旦a TransactionScope被处置或被收集而Complete未被执行,整个环境事务就会被回滚; 就是这样,游戏结束了.
事实上,SQL Server不都支持真正的嵌套事务,虽然它是可能的(虽然有点不直观),以实现与适当使用相同的最终结果SAVE TRAN声明.如果您需要此特定行为,则将此逻辑重新实现为存储过程(或其中几个)可能是您的最佳选择.