NHibernate相当于SQL“UPDATE表SET列=列+ ...”

时间:2011-10-11 13:47:28

标签: nhibernate concurrency

我正在尝试使用NHibernate更新销售系统中Quantity的{​​{1}}。

Product

然而,NHibernate将以这种形式生成SQL:

        using (var session = NHibernateSessionUtil.OpenSession())
        {
            using (var trans = session.BeginTransaction())
            {
                var product = session.Load<Product>(1);
                product.Quantity += 2;
                session.SaveOrUpdate(product);
                trans.Commit();
            }
        }

如果其他客户在处理此代码时更新了产品数量,则数量不正确。 到目前为止我能想到的解决方案是在进行更新之前锁定该行:

        UPDATE Product SET quantity = 2 WHERE id = 1;

但是,如果我需要更新一长串产品,这会影响其他客户。

在NHibernate中是否有一个等效的方法来生成SQL,如:

                ...
                var product = session.Load<Product>(1);

                // lock row for update
                session.Lock(product, LockMode.Upgrade);

                product.Quantity += 2;
                session.SaveOrUpdate(product);
                ...

任何建议?

更新

我尝试打开具有可序列化隔离级别的会话,如@Fran建议的那样:

    UPDATE Product SET quantity = quantity + 2 WHERE id = 1;

问题是在提交此事务之前由另一个客户端修改行时,会发生异常:

    ...
    using (var trans = session.BeginTransaction(IsolationLevel.Serializable))
    ...

是否意味着我们需要明确锁定需要更新的每一行?即:

    {"ERROR: 40001: could not serialize access due to concurrent update"}

如果需要锁定,使用和不使用 IsolationLevel.Serializable 打开交易有什么不同?

1 个答案:

答案 0 :(得分:0)

我认为这样做的唯一方法是将对象锁定在可序列化的事务中。

所以当你打开你的交易时,给它一个可序列化的隔离级别。这将锁定对象,直到您提交事务为止。