我在 LINQ2SQL 和事务方面遇到了重大性能问题。我的代码使用 IDE 生成的 LINQ2SQL 代码执行以下操作:
运行存储过程检查现有记录 如果记录不存在则创建 运行一个存储过程,将其自己的代码包装在事务中
当我在没有事务范围的情况下运行代码时,每秒迭代 20 次。一旦我将代码包装在事务范围内,它就会下降到每秒 3-4 次迭代。我不明白为什么在顶层添加事务会降低性能这么多。请帮忙?
带有事务的伪存储过程:
begin transaction
update some_table_1;
insert into some_table_2;
commit transaction;
select some, return, values
没有事务的伪 LINQ 代码:
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 代码:
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。 SQL Profiler 显示,在启用 transactionscope 的情况下,一些查询需要更长的时间,但我不确定为什么。所涉及的查询的生命周期非常短暂,并且我已经验证了正在使用的索引。我无法确定为什么添加父事务会导致性能下降如此之大。
有什么想法吗?
编辑:
我已将问题追溯到最终存储过程中的以下查询:
if exists
(
select * from entries where
ProfileID = @ProfileID and
Created >= @PeriodStart and
Created < @PeriodEnd
) set @Exists = 1;
如果我使用了 with(nolock) ,如下所示,问题就会消失。
if exists
(
select * from entries with(nolock) where
ProfileID = @ProfileID and
Created >= @PeriodStart and
Created < @PeriodEnd
) set @Exists = 1;
但是,我担心这样做可能会导致以后出现问题。有什么建议吗?
最佳答案
一旦您获得交易,一件大事就会发生变化 - isolation level 。您的数据库是否存在严重争用?如果是这样:默认情况下,TransactionScope 处于最高的“可序列化”隔离级别,其中涉及读锁、键范围锁等。如果它不能立即获取这些锁,那么它会减慢速度它被阻止了。您可以通过降低事务的隔离级别(通过构造函数)进行调查。例如(但选择您自己的隔离级别):
using(var tran = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions { IsolationLevel = IsolationLevel.Snapshot })) {
// code
tran.Complete();
}
但是,选择隔离级别...很棘手;可序列化是最安全的(因此是默认值)。您还可以使用诸如 NOLOCK
和 UPDLOCK
之类的粒度提示(但不能通过 LINQ-to-SQL)来帮助控制特定表的锁定。
您还可以调查速度减慢是否是由于尝试与 DTC 对话所致。启用 DTC 并查看是否加速。 LTM 很好,但我之前见过对单个数据库的复合操作升级为 DTC...
关于c# - LINQ2SQL 事务性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/856010/