Hibernate版本控制 - 管理单独的字段更新

时间:2012-11-26 21:00:29

标签: java hibernate backend spring-transactions application-design

我有一个后端应用程序,该应用程序没有任何用户界面。这些操作由服务器在UDP和TCP端口上侦听的传入数据触发。

我们有Customer表,该表有15个字段。每个字段代表一些关键细节或指向其他信息的指针。例如,

CUSTOMER_TABLE {
 ID,
 NAME,
 DEFAULT_ADDRESS_ID,
 EMAIL_ADDRESS,
 LAST_LOGIN,
 VERSION   <--- trying to introduce
}

除了ID之外,每个字段都可以通过不同的进程一次更新。当两个并发进程覆盖彼此的值时,我遇到了问题。所以,我介绍了VERSION - hibernate生成的版本字段。

现在假设Server1在时间T1选择版本#400的客户模型 Server2在时间T1选择版本#400

的客户模型

Server1更改EMAIL_ADDRESS并更新CUSTOMER(在T2),因此新版本号为401(生成休眠)。

Server2更改NAME并尝试在T3更新CUSTOMER,因为版本号比DB中的版本号旧,事务将失败。

由于应用程序是非用户界面应用程序,我们无法真正要求用户授权更改...我们必须优雅地处理它以便更改通过。

我有什么办法来处理这种情况?

该应用具有以下结构

Listening Port Handler -> Service Wrapped in Transaction -> DAO -> DB

并且对于下一个 - 这是一个免责声明 - 我知道这是一个糟糕的设计...但不幸的是,该应用程序已经从一个非交易应用程序演变为一个非常无计划的交易方式...而且我在确定“何时”修复整体设计时没有太多控制权。现在结构......

Listening Port Handler -> Service invoked to get the model(ModelX) -> DAO -> DB (yes you are right, the model goes out of transaction boundary ... :-( )
                       -> Invoke different independent operations, each operation wrapped in txn -> DAO -> DB
                       -> Modify Model (ModelX)
                       -> Update model(ModelX) as a separate transaction -> DAO -> DB

我将在第二个中遇到麻烦,我无法刷新我的模型,如果我这样做,我会失去所有在模型上更改的内容,否则我将不得不重复所有步骤,这可能导致其他成功的行动被解雇了两次(至少)

我的问题是 - 无论如何

  1. hibernate可以理解被修改的属性
  2. 检查版本
  3. 如果手头的版本陈旧,请获取新版本并在新版本上应用更改
  4. 保存对象(而不是抛出异常)

1 个答案:

答案 0 :(得分:0)

其中一个选项是使用HibernatedynamicInsert/dynamicUpdate功能。你必须摆脱版本控制。以下是Hibernate documentation的摘录:

  

dynamic-update(可选 - 默认为false):指定UPDATE   SQL应该在运行时生成,并且只能包含那些列   其价值已发生变化。

可以找到此功能的一个示例here