1

我在数据库中有一些序列,由范围表示。它包含三个字段: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 - 它只是我们使用的名称协议。

4

1 回答 1

0

I've used .Lock().Upgrade when the data is taken from DB, and everything worked. Thanks to hazzik for the link.

Now my code have this:

session.QueryOver<Sequence>().Lock().Upgrade.DoSomeFiltering().Single()
于 2012-10-30T11:21:21.257 回答