TransactionScope的当前实现缺乏在嵌套作用域中更改IsolationLevels的能力。
MSDN状态:当使用嵌套的TransactionScope对象时,所有嵌套的作用域都必须配置为使用完全相同的隔离级别,如果它们想加入环境事务。如果嵌套的ArgumentException对象试图加入环境事务,但它指定了不同的隔离级别,则会引发TransactionScope。
但是Server允许我们在任何时候更改隔离级别,为什么TransactionScope不允许?我还是不明白。
BCL中是否有关于嵌套SQL事务及其隔离级别的标准来禁止这种行为。我有什么选择?我当然不能设计类库和促进隔离级别,只是为了可以使用类库。
如果方法A()需要一个快照级别,并调用方法B(),它需要读取提交的级别。方法A()在由我开发的LibraryA中,方法B()在LibraryB中,该方法是由一家虚拟公司开发的。如果没有ArgumentException,A()如何调用B()
发布于 2010-08-24 14:39:29
这更多地是一个理论问题,而不是任何特定产品的问题。基本上,事务的原始概念具有所有的ACID属性:原子的、一致的、孤立的和持久的。
http://databases.about.com/od/specificproducts/a/acid.htm
现在,考虑什么是“隔离级别”:本质上,出于性能或其他原因,我们可以选择放弃数据库对ACIDity的部分或全部保证。孤立性和原子性是密切相关的,就像彼此的双重性一样。打破其中一个,而另一个则遭殃。
通常情况下,将事务分解为在特定SQL语句中可单独表示的部分,但要使您的保证有所帮助,您需要将它们封装在一个事务中,至少要有足够的隔离才能使整个shmear正常工作。
现在,如果您的事务中有一部分需要更大程度的隔离,那么整个事务也需要,否则它可能在敏感部分期间中断。相反,如果某个部分被赋予较低的隔离级别,那么很可能该部分的适当功能需要较少的隔离。(不要让我拿出一个很好的例子来说明什么时候这是真的。)
无论如何,数据库服务器无法判断实际需求是否兼容,因此它完全放弃了这个问题。
真正应该发生的是人们开发他们所需要的交易。我意识到这并不总是那么容易,但考虑到业务数据模式仅属于您,将随机SQL组件插入到一起并不是一件容易的事。
在处理集中式数据库(如SQL Server)时,最佳做法是设计整个事务,然后当您注意到设计之间的共性时,您可以在编写毛茸茸的代码之前对其进行筛选。
如果您确实需要在不同的数据存储库(或类似的)之间进行协调,那么就需要一个分布式事务管理器。它是一个单独的产品,甚至比数据库服务器更难实现。但这对于像自动取款机这样的东西是必要的,它要么给你钱,要么不给你的银行账户,这两者必须匹配。
祝好运!
发布于 2015-10-12 01:53:11
发布于 2022-02-01 18:48:41
是。您可以使用具有不同隔离级别的嵌套TransactionScopes。
正如你的话所说
如果要加入环境事务,所有嵌套作用域都必须配置为使用完全相同的隔离级别。
因此,如果B可能需要与环境事务不同的隔离级别,只需确保它不加入使用TransactionScopeOption.RequiresNew的环境事务
void A()
{
var options = new TransactionOptions()
{
IsolationLevel = IsolationLevel.Snapshot
}
using (var transaction = new TransactionScope(TransactionScopeOption.Required, options))
{
B();
}
}
void B()
{
var options = new TransactionOptions()
{
IsolationLevel = IsolationLevel.ReadCommitted,
};
// RequiresNew is the important bit
using (var transaction = new TransactionScope(TransactionScopeOptions.RequiresNew, options))
{
// Do stuff
}
}https://stackoverflow.com/questions/3557435
复制相似问题