简体   繁体   English

Spring 数据 Jpa 带有@Transactional 的@Lock 注释

[英]Spring Data Jpa @Lock annotation with @Transactional

As per java docs for @Lock annotations:根据 @Lock 注释的 java 文档:

Annotation used to specify the LockModeType to be used when executing the query.用于指定执行查询时要使用的 LockModeType 的注解。 It will be evaluated when using Query on a query method or if you derive the query from the method name.在查询方法上使用 Query 或从方法名称派生查询时,将对它进行评估。

As mentioned above it will be evaluated with @Query annotation or findBySomething..() method.如上所述,它将使用 @Query 注释或 findBySomething..() 方法进行评估。

But as per my finding, when i put @Lock annotation with @Transactional in any method, and get record from db in that transaction method it is acquiring lock on db rows, ideally it should not(correct me if i am wrong):但根据我的发现,当我在任何方法中使用@Transactional 放置@Lock 注释,并在该事务方法中从数据库获取记录时,它正在获取数据库行的锁定,理想情况下它不应该(如果我错了,请纠正我):

I verified this with two transactions T1 and T2 as follows:我用两个事务 T1 和 T2 验证了这一点,如下所示:

  1. Starts T1 first, and fetch some records from db and sleep that thread and did not update them.首先启动 T1,然后从 db 中获取一些记录并休眠该线程并且没有更新它们。

  2. Now start T2 on other method having same @Lock with pessimistic write and @Transactional annotation and fetch same records and trying to update them, But when it is trying to commit those changes it waits for some time and then throw exception saying PessimsticLock timeout exception现在在其他方法上启动 T2,该方法具有相同的 @Lock 与悲观写入和 @Transactional 注释并获取相同的记录并尝试更新它们,但是当它尝试提交这些更改时它等待一段时间然后抛出异常说 PessimsticLock 超时异常

@Transactional
@Lock(LockModeType.PESSIMISTIC_WRITE)
public boolean addInventory(Integer id){

   repo.findById(id)// #statement 1
}

also when #statement 1 is called it does not fire "select for update" query instead only fire select query.同样,当调用#statement 1 时,它不会触发“选择更新”查询,而只会触发 select 查询。

Is it true that @Lock can be used with @Transactional and all rows which are fetched under this transaction get lock? @Lock 是否可以与 @Transactional 一起使用并且在此事务下获取的所有行都获得锁定?

Using SpringBoot version 2.1.4.RELEASE使用 SpringBoot 2.1.4.RELEASE 版本

I was able to figure out the behavior which I was facing:我能够弄清楚我面临的行为:

@Lock annotation has not effect, if it put over method having @Transactional annotation only, it is working with @Query or findByXyz() method. @Lock 注释没有效果,如果它把只有@Transactional 注释的方法放在上面,它正在使用@Query 或findByXyz() 方法。

In my case, T2 transaction not able to commit because of database which is MySQL and have default transaction isolation level 'Repeatable Read' which do not allow to proceed T2 transaction until T1 commits.在我的情况下,T2 事务无法提交,因为数据库是 MySQL 并且具有默认事务隔离级别“可重复读取”,在 T1 提交之前不允许进行 T2 事务。

@Lock(LockModeType.PESSIMISTIC_WRITE) //will not have any effect
@Transactional
public Response handleRequest(){
  //no lock will acquire
// prior to know about mysql's repeatble read, i was having impression, any call to db in this method will lock the db rows, which is wrong
}


@Lock(LockModeType.PESSIMISTIC_WRITE)// will fire select for update
@Transactional
public findByUserId(){

// any db call from repo layer which have no lock annotations 

}
@Lock(LockModeType.PESSIMISTIC_WRITE)// will fire select for update
@Query("select u from user as u where u.id=:id")
@Transactional
public getByUserID(String id){

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM