有 Java 编程相关的问题?

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

在JavaSpring中调试事务性注释

更新现有代码,如下所示:

@Override
@Transactional
public void update(SomeObject someObj) throws BusinessServiceException {
    ...
    someObjectRepository1.update(someObj);
    someObjectRepository2.create(someObj);

    //New code below:
    someObjectRelatedService.doStuff(someObj);  // <--new code
    //Throws error, object does not exist in someObjectRepository2
}

这里的问题是someObjectRelatedService。doStuff需要someObjectRepository2的最新版本,但事务性注释阻止了这种情况的发生,它会在方法完全运行后更新存储库。我能够通过使用调试器并在两者之间运行数据库调用进行验证

处理这种情况的最佳方式是什么?是否仅在事务方法之外提取someObjectRelatedService调用


共 (1) 个答案

  1. # 1 楼答案

    本质上,您需要移动事务的边界。虽然手动刷新事务是一种选择,但我不建议这样做

    如果SomeObjectRepository2#create(...)的语义允许,最简单的修复方法是用@Transactional(isolation = Propagation.REQUIRES_NEW)注释这个方法

    如果这不可能,我建议进行以下小规模的重新设计。首先,我们使用一个方法创建一个新类,该方法应执行与所需数据相关的代码:

    @Component
    public class NewClass {
        final SomeObjectRepository2 someObjectRepository2;
    
        @Autowired
        public NewClass(final SomeObjectRepository2 someObjectRepository2) {
            this.someObjectRepository2 = someObjectRepository2;
        }
    
        @Transactional(isolation = Propagation.REQUIRES_NEW) // enforces new transaction
        public WhateverNeedsToBereturned newMethod(WhateverType someObject) {
            return someObjectRepository2.create(someObj);
        }
    }
    

    然后我们重写现有代码以使用新类:

    @Override
    @Transactional
    public void update(SomeObject someObj) throws BusinessServiceException {
        ...
        someObjectRepository1.update(someObj);
        newClassInstance.newMethod(someObj);
    
        //New code below:
        someObjectRelatedService.doStuff(someObj); 
        //Throws error, object does not exist in someObjectRepository2
    }
    

    请注意,您必须创建一个新类才能使其工作。通过this-引用的方法调用没有代理,因此@Transactional注释不会生效

    进一步注意newClassInstance必须通过DI容器注入,原因与此相同