内部TransactionScope具有不同的IsolationLevel,如何实现?

时间:2010-08-24 14:21:37

标签: .net ado.net transactionscope system.transactions

TransactionScope 的当前实现无法在嵌套作用域中更改IsolationLevels。

MSDN状态:使用嵌套的TransactionScope对象时,如果要加入环境事务,则必须将所有嵌套作用域配置为使用完全相同的隔离级别。如果嵌套的TransactionScope对象尝试加入环境事务,但它指定了不同的隔离级别,则抛出 ArgumentException

然而,SQL Server允许我们随时更改隔离级别,为什么TransactionScope不允许?我不明白。

BCL中是否有关于嵌套SQL事务及其隔离级别的标准禁止此行为。我有什么选择?我当然不能设计类库并提升它们的隔离级别,只是为了它们可以被使用。

如果方法 A()需要快照级别,并调用需要提交读取级别的方法B()。方法 A()在我开发的LibraryA中,方法 B()在由虚拟公司开发的LibraryB中。 A()如何在不获取 ArgumentException 的情况下调用 B()

2 个答案:

答案 0 :(得分:1)

这更像是一个理论问题,而不是任何特定产品。基本上,交易的原始概念具有所有ACID属性:原子,一致,隔离和持久。

http://databases.about.com/od/specificproducts/a/acid.htm

现在,考虑“隔离级别”的含义:基本上,出于性能或其他原因,我们可能会选择放弃数据库关于ACIDity的部分或全部保证。隔离和原子性密切相关,就像彼此的双重关系一样。打破一个,另一个受苦。

将事务分解为可在特定SQL语句中单独表达的部分是很常见的,但是为了保证提供帮助,您需要将它们包装在事务中,并且至少有足够的隔离以使整个shmear工作正常。

现在,如果您事务的某些部分需要更大程度的隔离,那么整个事务也会发生,否则它可能会在敏感部分中断。相反,如果某些部分的隔离程度较低,那么很可能该部分的正常功能需要较少的隔离。 (不要让我想出一个很好的例子,说明这可能是真的。)

无论如何,数据库服务器无法确定实际要求是否兼容,因此它完全放弃了这个问题。

真正应该发生的是人们开发他们需要的交易。我意识到这并不总是那么容易,但鉴于你的业务数据模式是你自己的事实,将随机SQL组件插在一起并不容易。

在处理集中式数据库(如SQL Server)的情况下,最佳做法是设计整个事务,然后当您注意到设计之间的共性时,可以在编写毛茸茸的代码之前将其分解出来。

如果您确实需要在不同的数据存储库(或类似存储库)之间进行协调,则需要调用分布式事务管理器。它是一个单独的产品,甚至比数据库服务器更难获得。但这对于像ATM这样的东西来说是必要的,这些东西既可以给你钱,也可以不给你,或者你的银行账户或不是你的银行账户,这两者必须匹配。

祝你好运!

答案 1 :(得分:0)

我发现自己陷入了麻烦,一旦我猜错了选项所有的麻烦,你就无法实现类似的东西。事实上,如果切换隔离级别,每个连接只允许一个隔离级别然后改变整个隔离级别,直到嵌套完成。

查看this stackpost

阅读isolation remarks