事务和事务范围隔离



我必须向我的数据库添加很多信息。添加此信息大约需要 5-7 分钟。我需要添加交易。

我试过这个:

try { 
    db.Connection.Open();
    db.Transaction = db.Connection.BeginTransaction(); 
    UpdateTable1();
    UpdateBigTable2();
    ...
    db.Transaction.Commit(); 
} catch {
    db.Transaction.Rollback();  
}

但是当我的数据库更新时,我无法读取数据库或对数据库执行任何操作。

我试图设置IsolationLevel,但没有任何帮助。

我试过这个:

using (var ts = new TransactionScope()) {
    UpdateTable1();
    ts.Complete();
}

但是程序在 2-3 分钟后崩溃。

这个解决方案也没有帮助:

var transactionOptions = new TransactionOptions();
transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.Serializable;
transactionOptions.Timeout = TimeSpan.MaxValue;
using (var ts = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
{
    ...
}

如果我设置了数据库,则在更新时,我可以访问TransactionScopeOption.Suppress但在这种情况下,事务不起作用。

是的,如果您启动的事务需要大量记录,并且需要很长时间才能完成,那么作为直接结果,竞争操作将被阻止。对于"可序列化"事务尤其如此,因为它们占用的锁最多(包括键范围锁等)。这是交易的本质;它是酸中的我。

选项:

  • 不要在一笔巨额交易中做所有事情
  • 让您的读取操作故意读取锁(这是巨大的双刃剑 - 可能没问题,但可能会导致大问题 - 谨慎对待) - 例如NOLOCKREAD UNCOMMITTED
  • 在完整的 SQL 服务器(不是 CE)上,尝试使用快照隔离
using (var trans = new TransactionScope(
 TransactionScopeOption.Required, 
    new TransactionOptions
    {
        IsolationLevel = IsolationLevel.ReadUncommitted
    }
))
{
    // Your LINQ to SQL query goes here where you read some data from DB
}

在更新表(插入、删除或更新)时,它们会被锁定,因此,如果要读取尚未提交的数据,则可以使用 Transaction IsolationLevel.ReadUncommit 来允许脏读取

你试过这个吗?

transactionOptions.Timeout = TransactionManager.MaximumTimeout;

最新更新