我有一个漫长的过程,可以在我的数据库中的每个用户上运行并更新"得分"和"命中"字段,当它正在运行时,有时用户会尝试更新他的名字/电话等,当发生这种情况时,用户更新失败并显示:
org.springframework.dao.CannotAcquireLockException
could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.LockAcquisitionException: could not execute statement
问题是,我知道用户无法更新他的得分/命中字段,那么我可以阻止该行被锁定并允许两个更新运行吗? (我正在使用hibernates @DynamicUpdate,因为我认为这会阻止锁定,因为查询只会更新已更改的字段,但没有运气)
BTW我正在使用Spring引导1.3.3.RELEASE和java 8,(在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 { ..
我仍然得到锁定异常。我还在做错什么吗?
答案 0 :(得分:1)
暂时将更新的用户记录保存到另一个表中,并且在长时间运行的进程完成后,还有另一个进程将此数据放入用户表(也可能是长时间运行进程的最后一步)。
向用户显示个人资料页面(或者他可以更新其记录的页面)时,您必须在主用户表(可能被锁定)和另一个表内的内容之间进行聚合。
更新用户记录时,请捕获CannotAcquireLockException,并将信息保存到回退表。