我需要在生产环境中执行一个长时间运行的进程(请不要问为什么),我在这个进程中使用 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();
最佳答案
锁定可能是 Sql Server 锁定升级的结果。我建议您将事务分成更小的批处理,在一个事务中仅索引 50-100 个实体,提交它,在另一个事务中索引下一批。
顺便说一句,ISession 不是为批处理而设计的,与 IStatelessSession 相比会消耗更多的内存。
而且我认为在这种事务中使用 ReadUncommitted 并不是一个好主意。 ReadUncommitted 可能适用于非关键的只读事务,例如用于显示目的的列表。没有非锁定事务这样的东西。
关于c# - NHibernate 中的非锁定事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19646051/