【发布时间】:2020-10-24 10:15:00
【问题描述】:
我们有一个 Spring Boot 应用程序,它严重依赖 SimpleJpaRepository 实现来执行数据库 CRUD 操作。
问题:该类被@Transactional注解,导致所有调用的方法都被包装在一个SQL事务中。
我们希望我们的存储库只为插入/更新/删除操作生成 SQL 事务,而不是为选择操作生成 SQL 事务(除非它们是从另一个用 @Transactional 注释的方法调用的)
我们如何设置我们的存储库来实现这一点,什么是不太明显的效果? (我认为这个类被这样注释是有原因的)
代码和日志
调用@Transactional 方法,预期1 个事务,找到1 个(OK)
@Transactional
public User readUser(int id){
userRepository.findOne(id);
roleRepository.findByUser(id);
}
SQL 探查器:
set implicit_transactions on
exec sp_executesql N'select userentity0_.id as id1_45_, .....'
exec sp_executesql N'select roleassign0_.id as id1_36_, ....'
IF @@TRANCOUNT > 0 COMMIT TRAN
如果没有 @Transactional,预计没有交易,找到 2,由存储库创建 (BAD):
public User readUser(int id){
userRepository.findOne(id);
roleRepository.findByUser(id);
}
SQL 探查器:
set implicit_transactions on
exec sp_executesql N'select userentity0_.id as id1_45_, .....'
IF @@TRANCOUNT > 0 COMMIT TRAN
set implicit_transactions on
exec sp_executesql N'select roleassign0_.id as id1_36_, ....'
IF @@TRANCOUNT > 0 COMMIT TRAN
【问题讨论】:
-
您是否从类或方法中调用这些方法,并使用事务性注释?您可以使用事务性注释其中一种方法来测试它,并将传播级别设置为
NEVER。如果你从事务中调用它,它会抛出一个异常。 -
我不希望它抛出异常。我希望它不会为我们所做的每个查询创建一个隐式事务。添加详细日志
-
您的存储库方法是如何实现的?他们使用弹簧数据存储库吗?
-
您是否根本不希望非注释方法的任何事务?
-
@KavithakaranKanapathippillai 所有存储库都从 spring-data-jpa 实现
SimpleJpaRepository
标签: java sql-server spring spring-boot transactions