我在数据库中有一些序列,由范围表示。它包含三个字段:beginId、nextId 和 endId。
任务是从这个范围中获取nextId,并确保它是唯一的。代码可以在高度并行化的环境中运行,具有许多线程,在许多机器上。
我需要做什么:
lock(database)
{
var seq = GetSequence()
var acquiredId = seq.NextId;
seq.NextId++
Save(seq)
}
所以我使用这段代码:
using (ISession session = GetSessionFactory().OpenSession())
using (ITransaction transaction = session.BeginTransaction(IsolationLevel.RepeatableRead))
{
var sequence = session.CreateCriteria<Sequence>().Single(); // This line is simplified
var allocatedId = sequence.NextId;
sequence.NextId++;
session.SaveOrUpdate(sequence);
transaction.Commit();
return allocatedId;
}
但是由于某种原因,当我在多线程中运行此代码进行测试时,我收到了多次分配的相同 ID。我正在使用带有 RepeatableRead 锁的事务,但这无济于事。
PS Id 并不意味着表的 Id - 它只是我们使用的名称协议。