我有一个后端应用程序,该应用程序没有任何用户界面。这些操作由服务器在 UDP 和 TCP 端口上侦听的传入数据触发。
我们有 Customer 表,该表有 15 个字段。每个字段代表一些关键细节或指向其他信息的指针。例如,
CUSTOMER_TABLE {
ID,
NAME,
DEFAULT_ADDRESS_ID,
EMAIL_ADDRESS,
LAST_LOGIN,
VERSION <--- trying to introduce
}
除了 ID 之外,这些字段中的每一个都可以由不同的进程一次更新。当两个并发进程覆盖彼此的值时,我遇到了问题。所以,我介绍了 VERSION - hibernate 生成的版本字段。
现在假设服务器 1 在时间 T1 选择了版本#400 的客户模型 服务器 2 在时间 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
我在第二个中会遇到问题,我无法刷新我的模型,因为如果我这样做了,我将失去对模型所做的所有更改,或者我将不得不再次重复所有步骤,这可能会导致其他成功操作开火两次(至少)
我的问题是 - 无论如何
- hibernate可以理解被修改的属性
- 检查版本
- 如果手头的版本过时,请获取新版本并在新版本上应用更改
- 保存对象(而不是抛出异常)