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 锁升级的结果。我建议您将事务分成更小的批次,在一个事务中仅索引 50-100 个实体,提交它,在另一个事务中索引下一批。

顺便说一句,ISession 不适合批处理,与 IStatelessSession 相比,它会消耗更多的内存。

而且我认为在这种事务中使用 ReadUncommitted 并不是一个好主意。ReadUncommitted 对于非关键的只读事务(例如用于显示目的的列表)可能是可以的。没有非锁定事务之类的东西。

于 2013-10-29T03:31:21.333 回答