2

実稼働環境で長時間実行するプロセスを実行する必要があります (理由は聞かないでください)。このプロセスで ReadUncommited を使用してトランザクションを開いていますが、関連するすべてのテーブルがロックされており、テーブルでいくつかの更新を実行しています。したがって、このプロセスを実行してから、これらのテーブルのいずれかに対してクエリを実行しようとすると、ロックが原因でクエリがタイムアウトします。

私のトランザクションがテーブルをロックしないということはありますか? トランザクションを使用しない場合、テーブルはロックされません。

これが私のコードです

ISession session = sessionProvider.GetCurrentSession();
session.SetBatchSize(100);
session.BeginTransaction(IsolationLevel.ReadUncommitted);

var solrCandidateFactory = _container.GetInstance<ISolrCandidateFactory>();
int id;

while (concurrentQueue.TryDequeue(out id))
{
    var cv = session.Get<Curriculum>(id,LockMode.None);
    SolrCandidate fromCandidate = solrCandidateFactory.CreateFromCandidate(cv);

    _candidateIndexer.Index(fromCandidate);

    session
        .CreateSQLQuery("update Curriculum set IndexedAt = :time where Id = :id")
        .SetParameter("time", DateTime.Now)
        .SetParameter("id", id)

        .ExecuteUpdate();
}

session.Transaction.Commit();
4

1 に答える 1

0

ロックは、Sql Server ロックのエスカレーションの結果である可能性があります。トランザクションを小さなバッチに分割し、1 つのトランザクションで 50 ~ 100 のエンティティのみをインデックス化し、それをコミットし、別のトランザクションで次のバッチをインデックス化することをお勧めします。

ちなみに、ISession はバッチ処理用ではなく、IStatelessSession と比較してより多くのメモリを消費します。

そして、この種のトランザクションで ReadUncommitted を使用するのは得策ではないと思います。ReadUncommitted は、表示目的のリストなど、重要ではない読み取り専用トランザクションでは問題ない場合があります。非ロックトランザクションなどはありません。

于 2013-10-29T03:31:21.333 に答える