@Transactional 对 JpaRepository 没有影响
@Transactional has no effect on JpaRepository
我在控制器层有一个父事务,但我想在调用存储库时启动一个新事务,为了实现这一点,我尝试如下注释存储库接口
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW)
public interface EventRepo extends JpaRepository<Event, Integer>{ }
然而,这似乎不会在调用 EventRepo#save 时启动新事务。为什么?
这是我的服务层。
public interface IApplicationService {
void save(Event event);
}
@Service
public class ApplicationService implements IApplicationService {
@Autowired
private EventRepo eventRepo;
@Override
public void save(Event event) {
eventRepo.save(event);
}
}
从controller层依次调用
@RequestMapping(value="/{indicator}", method=RequestMethod.POST)
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW)
@ResponseBody
public String processRequest(@PathVariable Integer indicator) {
Event event = new Event("Student1");
service.save(event);
if(indicator != 0) {
throw new RuntimeException();
}
return "Success";
}
然而,如果我用 @Transactional 注释服务接口,一切都会完美无缺
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW)
public interface IApplicationService {
void save(Event event);
}
当我说工作的意思是,如果我 运行 下面的 curl 命令,我将在 h2 db 中看到事件实体的 2 行
curl -X POST http://localhost:8080/1
curl -X POST http://localhost:8080/0
我理解最好在服务层控制事务,然后在存储库或控制器层控制事务,以这种方式构建情况可以很容易地演示问题。
Spring开机启动版本为2.5.6
下面的依赖项具有由 springboot starter
管理的版本
- spring-boot-starter-data-jpa
- spring-boot-starter-web
- 龙目岛
- h2
这里有一个帖子建议注释 Repository 层应该没问题,尽管不鼓励这样做。
@Transactional on a JpaRepository
在this Spring article中我们可以读到以下内容:
Additionally, we can get rid of the @Transactional annotation for the method as the CRUD methods of the Spring Data JPA repository implementation are already annotated with @Transactional.
对我来说,这意味着您添加到 EventRepo
的任何 @Transactional
注释都将被上面提到的 CRUD 方法中的 @Transactional
注释覆盖。话虽如此,我真的怀疑 @Transactional
注释对 JpaRepository
方法有任何影响。它在您自己的自定义方法中会有,但在我看来它在继承的方法中有 none。
为了在 EventRepo#save
中应用您自己的事务设置,覆盖保存方法:
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW)
public interface EventRepo extends JpaRepository<Event, Integer>{
@Override
Event save(Event event);
}
说明
Spring 忽略您的 @Transactional
注释,因为它无法在 EventRepo
代理中找到 save
方法,并应用来自父 CrudRepository
的默认事务设置]界面。
我在控制器层有一个父事务,但我想在调用存储库时启动一个新事务,为了实现这一点,我尝试如下注释存储库接口
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW)
public interface EventRepo extends JpaRepository<Event, Integer>{ }
然而,这似乎不会在调用 EventRepo#save 时启动新事务。为什么?
这是我的服务层。
public interface IApplicationService {
void save(Event event);
}
@Service
public class ApplicationService implements IApplicationService {
@Autowired
private EventRepo eventRepo;
@Override
public void save(Event event) {
eventRepo.save(event);
}
}
从controller层依次调用
@RequestMapping(value="/{indicator}", method=RequestMethod.POST)
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW)
@ResponseBody
public String processRequest(@PathVariable Integer indicator) {
Event event = new Event("Student1");
service.save(event);
if(indicator != 0) {
throw new RuntimeException();
}
return "Success";
}
然而,如果我用 @Transactional 注释服务接口,一切都会完美无缺
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW)
public interface IApplicationService {
void save(Event event);
}
当我说工作的意思是,如果我 运行 下面的 curl 命令,我将在 h2 db 中看到事件实体的 2 行
curl -X POST http://localhost:8080/1
curl -X POST http://localhost:8080/0
我理解最好在服务层控制事务,然后在存储库或控制器层控制事务,以这种方式构建情况可以很容易地演示问题。
Spring开机启动版本为2.5.6 下面的依赖项具有由 springboot starter
管理的版本- spring-boot-starter-data-jpa
- spring-boot-starter-web
- 龙目岛
- h2
这里有一个帖子建议注释 Repository 层应该没问题,尽管不鼓励这样做。 @Transactional on a JpaRepository
在this Spring article中我们可以读到以下内容:
Additionally, we can get rid of the @Transactional annotation for the method as the CRUD methods of the Spring Data JPA repository implementation are already annotated with @Transactional.
对我来说,这意味着您添加到 EventRepo
的任何 @Transactional
注释都将被上面提到的 CRUD 方法中的 @Transactional
注释覆盖。话虽如此,我真的怀疑 @Transactional
注释对 JpaRepository
方法有任何影响。它在您自己的自定义方法中会有,但在我看来它在继承的方法中有 none。
为了在 EventRepo#save
中应用您自己的事务设置,覆盖保存方法:
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW)
public interface EventRepo extends JpaRepository<Event, Integer>{
@Override
Event save(Event event);
}
说明
Spring 忽略您的 @Transactional
注释,因为它无法在 EventRepo
代理中找到 save
方法,并应用来自父 CrudRepository
的默认事务设置]界面。