[英]NHibernate Equivalent to SQL “UPDATE table SET column = column + …”
I'm trying to update Quantity
of a Product
in a sale system using NHibernate. 我正在尝试使用NHibernate更新销售系统中的
Product
Quantity
。
using (var session = NHibernateSessionUtil.OpenSession())
{
using (var trans = session.BeginTransaction())
{
var product = session.Load<Product>(1);
product.Quantity += 2;
session.SaveOrUpdate(product);
trans.Commit();
}
}
However, NHibernate will generate an SQL in this form: 但是,NHibernate将以这种形式生成SQL:
UPDATE Product SET quantity = 2 WHERE id = 1;
If another client updates product quantity while this code is processing, the quantity will be incorrect . 如果在此代码处理过程中另一个客户更新了产品数量,则数量将不正确 。 The solution I can think of so far is to lock that row before making the update:
到目前为止,我能想到的解决方案是在进行更新之前锁定该行:
...
var product = session.Load<Product>(1);
// lock row for update
session.Lock(product, LockMode.Upgrade);
product.Quantity += 2;
session.SaveOrUpdate(product);
...
However, this can affect other client if I need to update a long list of products. 但是,如果我需要更新一长串产品,这可能会影响其他客户端。
Is there an equivalent method in NHibernate to generate SQL like: NHibernate中是否有等效的方法来生成SQL,例如:
UPDATE Product SET quantity = quantity + 2 WHERE id = 1;
? ?
any suggestion? 有什么建议吗?
Update 更新资料
I've tried opening session with serializable isolation level as @Fran suggested: 我已经尝试过以@Fran建议使用可序列化隔离级别打开会话:
...
using (var trans = session.BeginTransaction(IsolationLevel.Serializable))
...
The problem is when the row is modified by another client before this transaction is committed, an exception occurs: 问题是,在提交该事务之前,另一客户修改了该行时,会发生异常:
{"ERROR: 40001: could not serialize access due to concurrent update"}
does that mean we need to explicitly lock every row that need updating? 这是否意味着我们需要显式锁定需要更新的每一行? ie:
即:
var product = session.Load<Product>(1, LockMode.Upgrade);
if the locking is necessary, what is the different between opening transaction with and without IsolationLevel.Serializable ? 如果需要锁定,则在有和没有IsolationLevel.Serializable的情况下打开事务有什么区别?
the only way I see doing this is locking the object in a serializable transaction. 我看到的唯一方法是将对象锁定在可序列化的事务中。
so when you open your transactions give it an Isolation level of serializable. 因此,当您打开交易记录时,请为它提供一个可序列化的隔离级别。 This will lock the object until you commit the transaction.
这将锁定对象,直到您提交事务。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.