如何解决 OptimisticLockingFailureException?

How to resolve OptimisticLockingFailureException?

触发OptimisticLockingFailureException的代码:

@Test
public void shouldIncrementUserTotalLikesByOne() throws IllegalArgumentException, UserNotFoundException {
    databuilderService.createAll();

    User user = userService.findByEmail("abc@gmail.com");

    long numberOfLikeCount = user.getLikeCount(); 

    userService.incrementUserTotalLikesByOne(user.getId()); 

    userService.save(user);

    long numberOfUpdatedUpdatedCount = user.getLikeCount(); 

    Assert.assertNotNull(numberOfUpdatedUpdatedCount);

    Assert.assertEquals(numberOfUpdatedUpdatedCount, numberOfLikeCount+1);
}

调用UserService.save()时出现异常:

org.springframework.dao.OptimisticLockingFailureException: Optimistic lock exception on saving entity:

乐观锁定异常意味着被持久化的对象已经改变了它在数据库中的状态(其他一些事务保存了该对象)。

所以,这是一个特定领域的问题。你必须决定应该做什么。

基本上有两种选择:

  1. 向用户呈现错误。

  2. 从数据库中读取对象并合并更改。有了这个,您应该假设您可能会丢失其他事务所做的修改。

我解决了写测试用例时出现的OptimisticLockingFailureException,实际上我犯了两次保存实体的错误,userService.save(user); this statement is already written inuserService.incrementUserTotalLikesByOne(user.getId());

我的模型有问题。我添加了 @Version 注释,但错误地存在错误的字段类型,并且转换过程发生在写入 MongoDB 抛出 OptimisticLockingFailureException 异常的过程中。

将@Version 注释的字段形式 long 类型更改为 Long class 解决了我的问题:

import org.springframework.data.annotation.Version

@Version
private Long version

这篇博客文章提供了更多细节:https://aodcoding.wordpress.com/2015/07/06/preventing-lost-updates-in-mongo-with-spring-optimistic-locking/