当前位置: 首页 > 知识库问答 >
问题:

跨 2 个不同Hibernate会话的乐观锁定

越胤
2023-03-14

我在服务层内部编写了一个更新方法,就像这样,我对所有的CRUD操作都使用Spring-data JpaRepository。

    public Note updateNote(Note note, Long id) {
        Note current = repository.getOne(id);

        current.setTitle(note.getTitle());
        current.setDetail(note.getDetail());

        return repository.save(current);
    }

我想对此操作进行乐观锁定,因此我在 Note 实体中添加了一个版本字段。

共有1个答案

常翰
2023-03-14

2:不,乐观锁定不需要任何@Lock,使用@Version我们实现了乐观锁定。

1:现在您可以使用线程测试乐观锁定方案,下面我写了一些示例测试代码,您可以根据需要进行更新。

假设我有Note实体:

@Entity
@Data
@ToString
public class Note {
    @Id
    @GeneratedValue
    private Long id;

    @Version
    private int version;

    private String name;
}

此外,我还有用于执行DB操作的Note Repostory

@存储库

public interface NoteRepo extends JpaRepository<Note, Long> {
}

现在我有一个笔记服务

@Service
@AllArgsConstructor
public class NoteService {

    private final NoteRepo noteRepo;

    @Transactional
    public Note create() {
        Note note = new Note();
        note.setName("Test Sample");
        note = noteRepo.save(note);
        System.out.println(note);
        return note;
    }

    @Transactional
    public void update(Long id, String name) {
       Note note =  noteRepo.getById(id);
       note.setName(name );
       note = noteRepo.save(note);
    }
}

现在是时候用集成测试来测试乐观锁定了。

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes =Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class TestServiceTest {
 @Autowired
    private NoteService noteService;

    @Test
    void assertObjectOptimisticLockingFailure() throws InterruptedException {
        // Create a note, so after this we can perform updation
        Note note = noteService.create();

        //CountDownLatch required for wait test to complete
        CountDownLatch countDownLatch = new CountDownLatch(2);

       // Create 2 NoteThread to perform updation for exising note entity
        NoteThread xNote = new NoteThread("X", note.getId(), countDownLatch);
        NoteThread yNote = new NoteThread("Y", note.getId(), countDownLatch);

        xNote.start();
        yNote.start();

        countDownLatch.await();

        // Validate one of thread have ObjectOptimisticLockingFailureException

        assertTrue(xNote.hasObjectOptimisticLockingFailure() || yNote.hasObjectOptimisticLockingFailure());

    }

    class NoteThread extends Thread {
        private final String name;
        private final Long id;
        private final CountDownLatch countDownLatch;
        private Class exceptionClass;
        
        // verify exception
        boolean hasObjectOptimisticLockingFailure() {
            return this.exceptionClass == ObjectOptimisticLockingFailureException.class;
        }

       // Custome Thread class for performing note update and verify lock exception
        public NoteThread(String name, Long id, CountDownLatch countDownLatch) {
            this.name = name;
            this.id = id;
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            try {
                noteService.update(id, name);
            } catch (Exception e) {
                exceptionClass = e.getClass();
            }finally {
                countDownLatch.countDown();
            }
        }
    }
}
 类似资料:
  • 我有一个带有和的微服务。我使用注释对中的表执行操作。我遇到的问题是保存操作花费了太多的时间,所以我希望读取操作不被它阻塞。注意,保存是通过持久化实体来执行的。 当前,在所有并发保存操作完成之前,所有读取操作都不会返回结果,这意味着表被锁定。相反,我希望实现乐观锁定。我怎样才能做到呢?

  • 我刚刚发现,当我对Postgresql或MariaDB数据库使用乐观锁定时,我的应用程序表现不同,我想知道是否有人可以解释发生了什么,以及我如何才能使应用程序以相同的方式使用MariaDB?我使用Postgresl 10.5和MariaDB 10.3.10,带有InnoDB引擎和默认设置。我用的是Spring框架5.1.0版,Hibernate 5.3.6。 所以我的代码看起来像这样: 我还有一个

  • 在多用户环境中,在同一时间可能会有多个用户更新相同的记录,会产生冲突,解决方案有两种:乐观锁、悲观锁。 悲观锁在这里不讲,自行Google。 乐观锁假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性,不完整则更新失败。 乐观锁实现方式 使用整数表示数据版本号.更新时检查版本号是否一致,如果相等,则更新成功,且版本号+1.如果不等,则数据已经被修改过,更新失败。 使用时间戳来实现。 本质上也

  • 悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作 乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。 乐观锁与悲观锁的具体区别: http://www.cnblogs.com/Bob-FD/p/3352216.html

  • 乐观锁Version 要使用乐观锁,需要使用version标记 type User struct { Id int64 Name string Version int `xorm:"version"` } 在Insert时,version标记的字段将会被设置为1,在Update时,Update的内容必须包含version原来的值。 var user User engine

  • 我有一个关于Hibernate中乐观锁定的问题。我正试图深入乐观地锁定Hibernate,但我有一个疑问。Hibernate使用版本方法(整数或时间戳)来实现乐观锁定。要进行配置,可以使用@Version注释(或xml配置)并创建版本属性。另一个选项是在不使用乐观lock=“all”属性进行版本控制的情况下进行配置。 我的问题是,如果你没有定义任何版本属性,也没有指定乐观锁属性,在这种情况下,哪种