2

データベースに多くの情報を追加する必要があります。この情報の追加には、約 5 ~ 7 分かかります。そして、トランザクションを追加する必要があります。

私はこれを試しました:

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

しかし、データベースが更新されているときは、DB を読み取ったり操作したりできません。

を設定しようとしまし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 この場合、トランザクションは機能しません。

4

3 に答える 3

2

はい、多数のレコードを操作するトランザクションを開始し、完了するまでに時間がかかる場合、直接的な結果として、競合する操作がブロックされます。これは、「シリアル化可能な」トランザクションに特に当てはまります。これは、ほとんどのロック (キー範囲ロックなどを含む) を使用するためです。これがトランザクションの性質です。それは ACID の I です。

オプション:

  • 1 つの巨大なトランザクションですべてを実行しない
  • 読み取り操作で意図的にロックを超えて読み取るようにします (これは非常に両刃です。問題はありませんが、大きな問題を引き起こす可能性があります。注意して扱ってください)。たとえばNOLOCK、 またはREAD UNCOMMITTED.
  • 完全な SQL サーバー (CE ではない) では、スナップショット分離を使用してみてください
于 2012-10-05T08:21:56.703 に答える
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 を使用してダーティ リードを許可できます。

于 2012-10-05T08:23:29.813 に答える