Transaction和TransactionScope隔离

时间:2012-10-05 08:17:38

标签: c# linq transactions sql-server-ce

我必须向我的数据库添加很多信息。添加此信息大约需要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,我可以在更新时访问我的数据库 但在这种情况下,交易不起作用。

3 个答案:

答案 0 :(得分:2)

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

选项:

  • 不要在一次大型交易中做所有事情
  • 让您的阅读操作有意识地读取过去锁定(这是非常双重的 - 可以很好,但可能会导致大问题 - 谨慎对待) - 例如NOLOCKREAD UNCOMMITTED
  • 在完整的SQL服务器(而不是CE)上,尝试使用快照隔离

答案 1 :(得分:1)

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.ReadUncommitted来允许脏读

答案 2 :(得分:0)

你试过这个吗?

transactionOptions.Timeout = TransactionManager.MaximumTimeout;