首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >事务的LINQ2SQL性能

事务的LINQ2SQL性能
EN

Stack Overflow用户
提问于 2009-05-13 04:04:44
回答 2查看 975关注 0票数 2

我在LINQ2SQL和事务方面有一个很大的性能问题。我的代码使用IDE生成的LINQ2SQL代码执行以下操作:

运行存储的proc检查现有记录,如果记录不存在,创建记录,运行在事务中包装自己代码的存储proc

当我在没有事务范围的情况下运行代码时,每秒会得到20次迭代。一旦我将代码包装在事务范围内,它就会下降到每秒3-4次迭代。我不明白为什么在顶级添加一个事务会使性能降低这么多。请帮帮忙?

Psuedo使用事务存储proc:

代码语言:javascript
复制
begin transaction
update some_table_1;
insert into some_table_2;
commit transaction;

select some, return, values

没有事务的伪LINQ代码:

代码语言:javascript
复制
var db = new SomeDbContext();
var exists = db.RecordExists(some arguments);

if (!exists) {
    var record = new SomeRecord 
    {
        // Assign property values
    };

    db.RecordsTable.InsertOnSubmit(record);
    db.SubmitChanges();

    var result = db.SomeStoredProcWithTransactions();
}

具有事务的伪LINQ代码:

代码语言:javascript
复制
var db = new SomeDbContext();
var exists = db.RecordExists(some arguments);

if (!exists) {
    using (var ts = new TransactionScope()) 
    {
        var record = new SomeRecord 
        {
            // Assign property values
        };

        db.RecordsTable.InsertOnSubmit(record);
        db.SubmitChanges();

        var result = db.SomeStoredProcWithTransactions();
        ts.Complete();
    }
}

我知道事务没有升级到DTC,因为我已经禁用了DTC。sure显示,在启用事务作用域时,有些查询所需的时间要长得多,但我不知道为什么。所涉及的查询非常短,而且我已经使用了我已经验证过的索引。我无法确定为什么父事务的添加会导致如此高的性能。

有什么想法吗?

编辑:

我将问题追溯到最终存储过程中的以下查询:

代码语言:javascript
复制
if exists 
(
    select * from entries where 
        ProfileID = @ProfileID and 
        Created >= @PeriodStart and 
        Created < @PeriodEnd
) set @Exists = 1;

如果我有(Nolock),如下图所示,问题就会消失。

代码语言:javascript
复制
if exists 
(
    select * from entries with(nolock) where 
        ProfileID = @ProfileID and 
        Created >= @PeriodStart and 
        Created < @PeriodEnd
) set @Exists = 1;

然而,我担心这样做可能会在未来造成问题。有什么建议吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-05-13 05:32:58

一旦您得到一个事务,就会发生变化的一件大事-- 隔离水平。您的数据库是否处于激烈的争用状态?如果是这样的话:默认情况下,TransactionScope处于最高的“可串行化”隔离级别,这包括读取锁、键范围锁等。如果它不能立即获得这些锁,那么它将在阻塞时减速。您可以通过降低事务的隔离级别(通过构造函数)进行调查。例如(但是选择您自己的隔离级别):

代码语言:javascript
复制
using(var tran = new TransactionScope(TransactionScopeOption.Required,
    new TransactionOptions { IsolationLevel = IsolationLevel.Snapshot })) {
    // code
    tran.Complete();
}

然而,选择一个隔离级别是..。棘手;可序列化是最安全的(因此是默认的)。您还可以使用粒度提示(但不是通过LINQ)(如NOLOCKUPDLOCK )来帮助控制特定表的锁定。

你也可以调查经济放缓是否是由于试图与直接贸易委员会对话。启用DTC并查看它是否加速。LTM很好,但我以前见过一个数据库的复合操作升级到DTC .

票数 3
EN

Stack Overflow用户

发布于 2009-05-13 04:10:33

您调用的存储过程是否参与环境(父)事务?-这就是问题所在。

存储过程很可能参与环境事务,这导致了程度的提高。有一个这里的MSDN文章讨论它们是如何相互关联的。

从该条中:

“当TransactionScope对象加入现有的环境事务时,除非作用域中止事务,否则处理范围对象可能不会结束事务。如果环境事务是由根范围创建的,则只有当根范围被释放时,才会对事务进行提交。如果事务是手动创建的,则事务在中止或由其创建者提交时结束。”

还有一个关于嵌套事务的严肃的文档,看起来它可以直接应用在MSDN在这里上。

注意:

“如果事务处于活动状态时调用TransProc,则基本上忽略TransProc中的嵌套事务,并根据对外部事务所采取的最终操作提交或回滚其INSERT语句。”

我认为这解释了性能上的差异--本质上是维护父事务的成本。克里斯多夫的建议可能有助于减少间接费用。

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

https://stackoverflow.com/questions/856010

复制
相关文章

相似问题

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