我使用 SQL 时间戳列作为版本号在 NHibernate 中映射了一个具有乐观并发控制的实体。映射如下:
<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 基类的子类,它的乐观锁设置为版本。