NHibernate:同时选择MAX值

时间:2009-12-04 15:26:29

标签: nhibernate transactions

假设我需要选择最大值作为订单号。因此,我将选择MAX(数字),指定要订购的编号,并将更改保存到数据库。但是,如何防止他人弄乱这个号码呢?交易会吗?类似的东西:

     ordersRepository.StartTransaction();
     order.Number = ordersRepository.GetMaxNumber() + 1;
     ordersRepository.Commit();

上面的代码“锁定”是否会发生变化,以便订单号只能由一个数据库客户端读/写?鉴于事务是纯粹的NHibernate,而GetMaxNumber只是SELECT MAX(Number)FROM Orders。

1 个答案:

答案 0 :(得分:1)

ITransactionIsolationLevel.Serializable一起使用应该可以胜任。但是要注意表争用。如果您在桌面上有高频率更新,事情可能会减慢很长时间。您可能希望在使用GetMaxNumber()时对数据库中的匹配进行概要分析。

我必须做类似的事情来生成自定义ID 以实现高并发性。我的解决方案将ID生成移动到数据库中,并使用单独的Counter表来保存最大值。

使用单独的Counter表有两个加分点:

  • 删除Order
  • 上的争用
  • 通常更快
  • 如果它够小,可以固定在内存中

我还使用存储过程返回下一个可用的ID:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
  UPDATE [COUNTER] SET Value = Value + 1 WHERE COUNTER_ID = @counterId
COMMIT TRAN

RETURN [NEW_VALUE]

希望有所帮助。