2009-12-04 51 views
0

假设我需要选择最大值作为订单号。因此,我将选择MAX(数字),指定要订购的数量,并将更改保存到数据库。但是,如何防止他人弄乱号码?交易会做什么?例如:NHibernate:同时选择MAX值

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

上面的“lock”代码是否会更改,以便订单号码只能由一个DB客户端读取/写入?鉴于事务是简单的NHibernate的,并且GetMaxNumber只是执行SELECT MAX(Number)FROM Orders。

回答

1

使用ITransactionIsolationLevel.Serializable应该完成这项工作。不过,请注意表格争用。如果你在桌面上有高频更新,事情可能会减慢大的时间。使用GetMaxNumber()时,您可能想要分析db上的命中。

我不得不做类似的事情来生成定制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] 

希望有所帮助。