在spring Boot 中,我有一个名为process()的方法,它调用几个jpa repo方法。jpa repo方法是原生查询,是插入/更新/删除方法。我希望process()是事务性的(如果对repo的任何调用失败,整个process()方法都应该回滚)。似乎需要在repo方法上添加@transactional,即使process()有@transactional。但是添加@ transactional到repo方法意味着它们都是transactional的,并且会提交一次,所以如果方法3失败,那么方法1和2仍然会提交。有没有办法用@Modifying创建一个原生查询,而不用@Transactional?
举例来说:
@Service
class MyBatchClass{
@Autowired
MyRepo myRepo;
@Transactional
public void process() {
myRepo.method1();
myRepo.method2();
myRepo.method3();
}
}
字符串
repo类:
@Repository
public interface MyRepo extends PagingAndSortingRepository<..., Long> {
@Transactional
@Modifying
@Query(nativeQuery = true, value = "insert into my_table select * from other_table")
Long method1();
@Transactional
@Modifying
@Query(nativeQuery = true, value = "update my_table set my_col = ... ")
Long method2();
@Transactional
@Modifying
@Query(nativeQuery = true, value = "delete from my_table where .... ")
Long method3();
}
型
注意事项:请与任何告诉我不要使用本机查询而使用JPA实体的本能作斗争。你不知道我的数据模型或我试图做什么。显然,在没有JPA实体的情况下,批量更新/插入/删除更有效。我不想读取表的一百万行,更新一列为空,然后将一百万条记录写回表中。有些地方jpa福尔斯不足,一个简单的本地查询更好。在我的应用程序中的大多数用例中,我确实使用JPA和实体,但在这种情况下没有意义。我也不想使用纯jdbc调用对于这个用例。
1条答案
按热度按时间l2osamch1#
代码实际上正确工作,我只是犯了一个愚蠢的错误。问题是我从同一bean中的另一个方法调用process(),所以aop代理@transacion被忽略。我将process()移动到另一个服务,现在它的行为正确。