【问题标题】:NHibernate not throwing StaleObjectStateException when <Version> used and data changed in database当使用 <Version> 并且数据库中的数据发生更改时,NHibernate 不会抛出 StaleObjectStateException
【发布时间】:2010-12-21 20:39:37
【问题描述】:

我在 NHibernate 中使用 SQL 时间戳列作为版本号映射了一个具有乐观并发控制的实体。映射如下:

<class name="Entity" optimistic-lock="version" discriminator-value="0">
    <id name="id">
        <generator class="native" />
    </id>
    <version name="Version" column="Version" generated="always" unsaved-value="null" type="System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    ...
    <subclass name="ChildEntity" discriminator-value="1" />
</class>

我正在测试当数据库中的一行中的数据在获取和更新记录之间发生变化时会发生什么。为此,我直接针对表中正在由 NHibernate 更新的记录之一运行更新语句。这种直接更新会改变表中记录的版本号。

正如预期的那样,NHibernate 托管更新不会发生在特定行上(这很好)。但是,在提交期间不会引发异常。我希望在提交事务时会发生 StaleObjectStateException,以便我可以回滚事务并通知用户。这不是预期的行为吗?我错过了什么吗?

我提交事务的代码如下所示:

_session.BeginTransaction();
...
// load objects in session
IList<ChildEntity> toChange = _session.Find('some condition');
foreach ( var itemToChange in toChange )
{
     itemToChange.Status = Status.Updated;
}
...
_session.Transaction.Commit();

这些项目属于同一个会话,所有工作都在一个事务中完成。 ChildEntity 是 Entity 基类的子类,它的乐观锁设置为版本。

【问题讨论】:

    标签: nhibernate concurrency versioning optimistic-concurrency


    【解决方案1】:

    您如何修改数据?只有当 NHibernate 尝试更新行并且版本号不再相同时,才会抛出 StaleObjectException。其他列无关紧要。是否有可能在您的测试中没有更新版本号?

    前提是这样的:

    A.用户 A & B 从版本 = 1 的数据库中获取对象

    SQL:SELECT [object] FROM [TABLE] where id = [id] and Version = 1

    B.用户 A 更新对象,将版本更改为 2

    SQL:UPDATE [TABLE] SET [object] (&amp; Set Version = 2) where id = [id] and Version = 1 返回更新的 1 行

    C.用户 B 尝试更新对象,但将 StaleObjectException 作为版本 = 1 的更新对象(他在步骤 1 中获得的版本)更新了数据库中的 0 条记录。

    SQL:UPDATE [TABLE] SET [object] where id = [id] and Version = 1 返回 0 行更新并抛出 StaleObjectException。

    【讨论】:

      【解决方案2】:

      看来我的测试不准确。在测试中,我在其他事务更新记录后进行获取。此其他更新使该行不符合更新条件,因此未尝试更新。当我更改测试以在 Get 之后进行竞争更新时,StaleObjectStateException 按预期抛出。

      很抱歉给您带来了困惑。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-12
        • 1970-01-01
        • 2019-11-03
        • 2022-10-24
        • 2011-04-22
        • 1970-01-01
        相关资源
        最近更新 更多