我们有一个表,每个更新的值都有新行。主键由ID和时间戳组成。还有一个状态列。对于特定的ID,我们将在每次更新值时都有一行,我们使用具有最新时间戳的那一行来表示“当前”值。
我们有一个流程可以根据用户输入更新状态。因此,当用户单击UI中的按钮时,将使用新状态和新用户ID创建新行。
如果两个用户同时点击该按钮,我们只需插入两个新记录,其中一个将获胜(具有最新时间戳的记录)。我们希望避免让两个用户同时点击此按钮,并且可能会创建一个新行而不知道他们踩到别人的状态更改。在Oracle中,我们只是执行类似的操作并检查是否插入了一行(当用户查看页面时,PREVIOUS_KNOWN_MAX_TS是“当前”记录的TS):
INSERT INTO SOME_TABLE
(ID, REVISION_TS, USER_ID, STATUS, ...)
SELECT 1, 'SOME_TIMESTAMP', 'user123', 'NEW_STATUS', ...
FROM DUAL
WHERE NOT EXISTS
(SELECT *
FROM SOME_TABLE
WHERE USER_ID = 1
AND REVISION_TS >= 'PREVIOUS_KNOWN_MAX_TS'));
如果在用户查看页面的时间与插入用户更新信息的时间之间插入了插入,则插入不会发生,我们会通过知道插入零行来检测到。
有没有办法在Hibernate中执行此操作,还是应该尝试进行某种SELECT FOR UPDATE?
答案 0 :(得分:0)
如果使用org.hibernate.annotations.SQLInsert
注释实体类,则可以覆盖Hibernate生成的插入。这有点棘手,因为你必须以完全相同的方式使用绑定参数,Hibernate的常用插件会使用它们。