11. 事务和并发 / 11.3. 乐观并发控制(Optimistic concurrency control) / 11.3.1. 应用程序级别的版本检查(Application version checking)

未能充分利用Hibernate功能的实现代码中,每次和数据库交互都需要一个新的 Session,而且开发人员必须在显示数据之前从数据库中重 新载入所有的持久化对象实例。这种方式迫使应用程序自己实现版本检查来确保 对话事务的隔离,从数据访问的角度来说是最低效的。这种使用方式和 entity EJB最相似。

// foo is an instance loaded by a previous Session
session = factory.openSession();
Transaction t = session.beginTransaction();

int oldVersion = foo.getVersion();
session.load( foo, foo.getKey() ); // load the current state
if ( oldVersion!=foo.getVersion ) throw new StaleObjectStateException();
foo.setProperty("bar");

t.commit();
session.close();

version 属性使用 <version>来映射,如果对象 是脏数据,在同步的时候,Hibernate会自动增加版本号。

当然,如果你的应用是在一个低数据并发环境下,并不需要版本检查的话,你照样可以使用 这种方式,只不过跳过版本检查就是了。在这种情况下,最晚提交生效last commit wins)就是你的长对话的默认处理策略。 请记住这种策略可能会让应用软件的用户感到困惑,因为他们有可能会碰上更新丢失掉却没 有出错信息,或者需要合并更改冲突的情况。

很明显,手工进行版本检查只适合于某些软件规模非常小的应用场景,对于大多数软件应用场景 来说并不现实。通常情况下,不仅是单个对象实例需要进行版本检查,整个被修改过的关 联对象图也都需要进行版本检查。作为标准设计范例,Hibernate使用扩展周期的 Session的方式,或者脱管对象实例的方式来提供自动版本检查。