首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内部TransactionScope具有不同的IsolationLevel,如何实现?

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

Stack Overflow用户
提问于 2010-08-24 14:21:37
回答 3查看 5.3K关注 0票数 4

TransactionScope的当前实现缺乏在嵌套作用域中更改IsolationLevels的能力。

MSDN状态:当使用嵌套的TransactionScope对象时,所有嵌套的作用域都必须配置为使用完全相同的隔离级别,如果它们想加入环境事务。如果嵌套的ArgumentException对象试图加入环境事务,但它指定了不同的隔离级别,则会引发TransactionScope。

但是Server允许我们在任何时候更改隔离级别,为什么TransactionScope不允许?我还是不明白。

BCL中是否有关于嵌套SQL事务及其隔离级别的标准来禁止这种行为。我有什么选择?我当然不能设计类库和促进隔离级别,只是为了可以使用类库。

如果方法A()需要一个快照级别,并调用方法B(),它需要读取提交的级别。方法A()在由我开发的LibraryA中,方法B()在LibraryB中,该方法是由一家虚拟公司开发的。如果没有ArgumentExceptionA()如何调用B()

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-08-24 14:39:29

这更多地是一个理论问题,而不是任何特定产品的问题。基本上,事务的原始概念具有所有的ACID属性:原子的、一致的、孤立的和持久的。

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

现在,考虑什么是“隔离级别”:本质上,出于性能或其他原因,我们可以选择放弃数据库对ACIDity的部分或全部保证。孤立性和原子性是密切相关的,就像彼此的双重性一样。打破其中一个,而另一个则遭殃。

通常情况下,将事务分解为在特定SQL语句中可单独表示的部分,但要使您的保证有所帮助,您需要将它们封装在一个事务中,至少要有足够的隔离才能使整个shmear正常工作。

现在,如果您的事务中有一部分需要更大程度的隔离,那么整个事务也需要,否则它可能在敏感部分期间中断。相反,如果某个部分被赋予较低的隔离级别,那么很可能该部分的适当功能需要较少的隔离。(不要让我拿出一个很好的例子来说明什么时候这是真的。)

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

真正应该发生的是人们开发他们所需要的交易。我意识到这并不总是那么容易,但考虑到业务数据模式仅属于您,将随机SQL组件插入到一起并不是一件容易的事。

在处理集中式数据库(如SQL Server)时,最佳做法是设计整个事务,然后当您注意到设计之间的共性时,您可以在编写毛茸茸的代码之前对其进行筛选。

如果您确实需要在不同的数据存储库(或类似的)之间进行协调,那么就需要一个分布式事务管理器。它是一个单独的产品,甚至比数据库服务器更难实现。但这对于像自动取款机这样的东西是必要的,它要么给你钱,要么不给你的银行账户,这两者必须匹配。

祝好运!

票数 3
EN

Stack Overflow用户

发布于 2015-10-12 01:53:11

我发现自己陷入了麻烦,一旦我猜异常选项分类了所有,并且您无法实现类似的东西可以是done.the事实是,如果您切换隔离级别,那么整个隔离级别将被更改,直到嵌套完成为止,每个连接只允许一个隔离级别。

查看堆栈

阅读隔离备注

票数 0
EN

Stack Overflow用户

发布于 2022-02-01 18:48:41

是。您可以使用具有不同隔离级别的嵌套TransactionScopes

正如你的话所说

如果要加入环境事务,所有嵌套作用域都必须配置为使用完全相同的隔离级别。

因此,如果B可能需要与环境事务不同的隔离级别,只需确保它不加入使用TransactionScopeOption.RequiresNew的环境事务

代码语言:javascript
复制
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
    }

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3557435

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档