当使用<Version>并在数据库中更改数据时,NHibernate不会抛出StaleObjectStateException

Ste*_*ing 1 versioning nhibernate concurrency optimistic-concurrency

我有一个实体映射在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>
Run Code Online (Sandbox Code Playgroud)

我正在测试当数据库中的一行中的数据在记录的获取和更新之间发生变化时会发生什么.为此,我正在直接针对表中正在由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();
Run Code Online (Sandbox Code Playgroud)

这些项目属于同一会话,所有工作都在一个事务中完成.ChildEntity是Entity基类的子类,它将optimistic-lock设置为version.

Mic*_*uso 5

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

前提是:

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

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

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

SQL:UPDATE [TABLE] SET [object] (& 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.