有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Spring@Transactional何时锁定数据库表行

我使用的是Spring数据JPA,我有一个使用Spring的@Transactional注释的方法。在该方法中,我从数据库中获取实体。有些实体用于只读目的,而有些则在该事务中更新。让我们举个例子

@Transactional
public void method1(Long id) {
    var entityA = repositoryA.findById(id);
    var entityB = repositoryB.findByOtherId(id);

    entityA.setProperty1(entityB.getProperty() + 1);
}

@Transactional
public void method2(Long id) {
    var entityA = repositoryA.findById(id);
    var entityB = repositoryB.findByOtherId(id);

    entityA.setProperty2(entityB.getProperty() + 2);
}

在上面的例子中,假设entityAentityB分别对应于tableAtableB,并且property1property2tableA的两列。 此外,我使用的是SQL Server,因此默认隔离级别为READ_COMMITTED

我有以下问题:

  1. 在执行第var entityA = repositoryA.findById(id);行之后,如何确定应该获取哪种类型的锁?在上面的例子中,我们正在更新tableA中的数据,并在tableB中读取数据,所以在这里获得了不同的锁吗

  2. 假设method1method2都与相同的id同时被调用。获取锁的线程将首先阻塞第二个线程,还是两者并行执行?我知道隔离级别是READ_COMMITTED,但DB不知道我是否对第一个线程获取的行进行了任何更改

  3. 如果我想为同一个id并行执行这两个方法,应该设置什么隔离级别?同样,在这两种方法中,我都在更新同一行的不同列,所以当两个事务都提交时,结果是否与串行执行这些事务相同?另一方面,当Hibernate在提交阶段刷新更改时,对于update语句,它会更新实体的所有字段,所以在这种情况下会丢失更新吗

  4. 如果我在事务注释中指定readOnly=true,它会对锁的获取产生任何影响吗


共 (0) 个答案