2

我有一个漫长的过程,在我的数据库中的每个用户上运行并更新“分数”和“命中”字段,当它正在运行时,有时用户尝试更新他的姓名/电话等,当这种情况发生时用户更新失败:

org.springframework.dao.CannotAcquireLockException
could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.LockAcquisitionException: could not execute statement

问题是,我知道用户无法更新他的得分/命中字段,所以我可以防止该行被锁定并允许两个更新运行吗?(我正在使用休眠@DynamicUpdate,因为我认为这会阻止锁定,因为查询只会更新更改的字段,但没有运气)

顺便说一句,我正在使用带有 java 8 的 spring boot 1.3.3.RELEASE,(在 tomcat 中运行。

* 更新 *

为了回答@Thierry 的问题,我正在为所有用户得分/点击更新使用一笔大交易。我必须立即更新所有用户。而且我不能阻止用户在这个过程运行时更新他们的记录,因为这会严重影响他们对系统的使用。

* 更新 2 *

所以经过大量搜索后,我想我找到了我想要的东西。根据这篇文章: http: //www.intertech.com/Blog/hibernate-optimistic-lock-without-a-version-or-timestamp/,当我使用锁类型脏和动态更新设置乐观锁时:“这替代方案允许其他并发进程更新同一行,只要它们不修改相同的列。” 问题是我将我的实体设置为:

@DynamicUpdate
@OptimisticLocking(type = OptimisticLockType.DIRTY)
@Entity
public class User { ..

而且我仍然得到锁定异常。我还在做错什么吗?

4

1 回答 1

1

将更新的用户记录临时保存到另一个表中,并让另一个进程在长时间运行的进程完成后将此数据放入您的用户表中(也可能是长时间运行进程的最后一步)。

在向用户显示个人资料页面(或他可以更新其记录的页面)时,您必须在主用户表(可能被锁定)和另一个表内的内容之间进行聚合。

更新用户记录时,捕获 CannotAcquireLockException,并将信息保存到备用表。

于 2016-06-15T14:25:33.360 回答