跳到主要内容

版本模式

保存指令可以把根实体的@Version视为乐观锁,也可以把它视为普通赋值。默认仍然是 VersionMode.OPTIMISTIC_LOCK

模式更新时已加载的版本自动递增
OPTIMISTIC_LOCK添加隐式版本检查是,带版本的更新成功后递增
ASSIGNMENT由对象形状、mask和赋值控制

并发编辑需要检测过期版本时使用默认模式。导入由外部维护版本的数据,或实现显式版本策略时, 使用ASSIGNMENT。此时已加载的版本既不是隐式乐观锁条件,也不代表要求自动递增。

写入输入版本

假设store包含外部提供的版本以及插入所需的值。对于已有行,只接受更高的输入版本:

sqlClient
.saveCommand(store)
.setVersionMode(VersionMode.ASSIGNMENT)
.setUpdateWhere(
BookStoreTable.class,
(table, values) -> values.newNumber(BookStoreProps.VERSION).gt(table.version())
)
.execute();

被接受的更新会原样写入输入版本。更低或相等的版本被正常拒绝,可检查结果是否被接受。 新行的插入不受更新条件限制。

未加载的版本在插入时仍然获得框架初始值。在赋值模式下,如果更新mask排除了已加载版本, 冲突时数据库中的版本会保持不变。

计算下一个版本

赋值模式下,@Version也可以作为保存赋值表达式的目标:

sqlClient
.saveCommand(store)
.setVersionMode(VersionMode.ASSIGNMENT)
.set(
BookStoreTable.class,
BookStoreProps.VERSION,
(target, values) -> target.version().plus(1)
)
.execute();

普通保存赋值规则仍然适用:目标必须已加载,而且被mask选中用于更新。需要比较后递增时, 应显式添加setUpdateWheresetOptimisticLock条件,对比数据库版本和输入版本。

警告

setVersionMode只作用于根实体,不会传播到图保存中的关联实体。切换到ASSIGNMENT会移除隐式 版本保护,不会暗中替换成另一种检查。

从查询插入或upsert对版本使用赋值语义,source中的版本值不会意外启用乐观锁。