我正在尝试使用一些环境事务范围(感谢Entity Framework),这是我以前没有做过的,我看到了一些奇怪的行为,我正在努力理解。
我正在尝试加入当前事务范围并在其成功完成后进行一些操作。我的加入参与者由于持有某些资源而实现IDisposable
。我有一个简单的示例展示了奇怪的行为。
对于这个类,
class WtfTransactionScope : IDisposable, IEnlistmentNotification
{
public WtfTransactionScope()
{
if(Transaction.Current == null)
return;
Transaction.Current.EnlistVolatile(this, EnlistmentOptions.None);
}
void IEnlistmentNotification.Commit(Enlistment enlistment)
{
enlistment.Done();
Console.WriteLine("Committed");
}
void IEnlistmentNotification.InDoubt(Enlistment enlistment)
{
enlistment.Done();
Console.WriteLine("InDoubt");
}
void IEnlistmentNotification.Prepare(
PreparingEnlistment preparingEnlistment)
{
Console.WriteLine("Prepare called");
preparingEnlistment.Prepared();
Console.WriteLine("Prepare completed");
}
void IEnlistmentNotification.Rollback(Enlistment enlistment)
{
enlistment.Done();
Console.WriteLine("Rolled back");
}
public void Dispose()
{
Console.WriteLine("Disposed");
}
}
当按照这里展示的使用时
using(var scope = new TransactionScope())
using(new WtfTransactionScope())
{
scope.Complete();
}
控制台输出表明出现了意外情况:
已释放
已调用 Prepare
已提交
Prepare 已完成
啥?
我在事务完成之前被释放了。这......有点否定了与事务范围一起工作的好处。我希望一旦事务成功(或失败),我就会收到通知,以便我可以进行一些操作。不幸的是,我假设这将发生在 scope.Complete()
之后,在我们移出 using
范围之前被释放。显然,这并非如此。
当然,我可以通过“黑科技”解决这个问题。但是我还有其他问题,这些问题本质上阻止我这样做。在这种情况下,我必须使用其他方法来解决。
我在这里做错了什么吗?还是这是预期行为?可以采取不同的方法来防止这种情况发生吗??