.NET中的嵌套事务
我怎样才能做到这一点? 我的理解是,这对于TransactionScopes来说是不可能的,但我想以其他方式完成相同的操作:
业务逻辑类:
public bool Bar()
{
try
{
using (var tsWork = new TransactionScope())
{
ComplicatedDataImportCode(somedata);
FlagRecordInDatabaseAsImported(); // this is the same record that's modified in the catch
tsWork.Complete();
return true;
}
catch (DuplicateDataException err)
{
// if we got here, the above transaction should have rolled back,
// so take that same record in the database and update it to "Duplicate".
FlagSameRecordInDatabaseAsDuplicate(err.Message);
}
return false;
}
现在,这工作正常,直到我封装一个事务的所有内部(也许是一个集成测试,我想要执行断言后回滚)。
简单的测试来证明我的观点:
public void CanTest()
{
// Arrange
var foo = new Foo();
using (var ts = new TransactionScope())
{
// Act
var success = foo.Bar();
// Assert
if (success)
{
Assert.That(SomethingThatTestsThatTheDataWasImported);
}
else
{
Assert.That(SomethingThatTestsThatTheRecordWasMarkedAsDuplicate);
}
// Now that we have been able to perform our Asserts, rollback.
}
}
最终,可以修改Foo.Bar()
的代码以适应解决方案,但是,无法为此解决方案修改ComplicatedDataImportCode()
的代码,因此我确实需要确保在故障情况下正确回滚。
我再次明白,根据我在本问题开始时引用的帖子,TransactionScopes不能用于这样做。 我在这里使用了TransactionScopes来表明我想要做什么,并且正在寻找实现此功能的最佳替代方法。
是不是因为这个必须得到你使用的DBMS的支持?
SQL Server并不真正支持嵌套事务,但是,对于SQL Server,您可以使用保存点。
几年前我在博客上写过的一篇文章。
如果您可以获得ComplicatedDataImportCode
正在使用的活动数据库连接,则只需在该连接上运行BEGIN TRAN
和ROLLBACK TRAN
。