代码之家  ›  专栏  ›  技术社区  ›  João Menighin

处理异常时保存不起作用

  •  3
  • João Menighin  · 技术社区  · 6 年前

    我面临着一个甚至找不到调试方法的情况。

    我有以下内容 spring-data 储存库:

    集成日志存储库

    public interface IntegrationLogRepository extends PagingAndSortingRepository<IntegrationLog, Long> {
    
    }
    

    养殖业

    public interface FooRepository extends PagingAndSortingRepository<Foo, Long> {
    
    }
    

    在我的业务逻辑上,我有如下内容:

    IntegrationLog log = new IntegrationLog();
    log.setTimestamp(new Date());
    
    try {
        Foo foo = new Foo();
    
        // Build the Foo object...
    
        fooRepository.save(foo);
        log.setStatus("OK");
    } catch (Exception e) {
        log.setStatus("NOK");
    } finally {
        integrationLogRepository.save(log);
    }
    

    当集成运行良好时, log 与保存 OK 状态。一切都很好。但当我有例外的时候,出于某种原因 integrationLogRepository.save(log) 什么都不做。我什么也没说:没有异常被抛出,我看不到在我的WebLogic控制台上执行任何休眠查询。日志未持久化…

    你知道为什么会这样吗?

    以下是我的依赖项:

    compile 'org.springframework.boot:spring-boot-starter-data-rest'
    compile 'org.springframework.boot:spring-boot-starter-security'
    compile "org.springframework.boot:spring-boot-starter-web-services"
    runtime 'org.springframework.boot:spring-boot-devtools'
    compile 'org.springframework.boot:spring-boot-starter-data-jpa'
    compile "org.springframework.boot:spring-boot-starter-websocket"
    compile 'javax.servlet:javax.servlet-api:3.1.0'
    compile 'org.hibernate:hibernate-core:5.1.16.Final'
    compile 'org.hibernate:hibernate-validator:5.2.3.Final'
    compile 'org.hibernate:hibernate-entitymanager:5.1.0.Final'
    

    在弹簧靴上运行 1.5.15.RELEASE ,爪哇 1.7 WebLogic 12.1.3 .

    谢谢!

    1 回复  |  直到 6 年前
        1
  •  0
  •   Rentius2407    6 年前

    引发的异常也在回滚集成日志保存。 如果要保存日志,则在保存时必须为其提供单独的事务。

    将日志存储库抽象为服务,并在保存日志的服务方法上添加创建新事务的事务。

    @Service
    public class IntegrationLogService {
    
        private final IntegrationLogRepository logRepository;
    
        @Autowired
        public IntegrationLogService(IntegrationLogRepository logRepository) {
            this.logRepository = logRepository;
        }
    
        @Transactional(propagation = Propagation.REQUIRES_NEW)
        public void save(Log log) {
            this.logRepository.save(log);
        }
    }
    

    在您的业务中替换

    finally {
        integrationLogRepository.save(log);
    }
    

    具有

    finally {
        integrationLogService.save(log);
    }
    

    编辑

    为什么设置 @Transactional(propagation = Propagation.NOT_SUPPORTED) 在业务层工作?

    为了理解它为什么起作用,我们需要先看看当一个人打电话时会发生什么。 save 在Spring中使用 org.springframework.data.repository.CrudRepository .

    弹簧试图确定 TransactionAttribute 在方法和TargetClass上。对于该方法 节约 和班 CrudRepository 总之,没有发现任何。春季使用 SimpleJpaRepository 作为默认实现的 粗砧 ,如果它在您的上找不到任何事务性属性,它将使用中指定的属性。 简单假设 .

    @Transactional
    public <S extends T> S save(S entity)
    

    默认传播 @Transactional 是必需的。

    Propagation propagation() default Propagation.REQUIRED;
    

    支持当前事务,如果不存在则创建新事务。

    从上面的文档中可以看到,如果没有指定事务,它将创建一个新事务。所以当您将业务层上的事务设置为 NOT_SUPPORTED (非交易性执行),实际 粗砧 是否创建了自己的事务,这意味着回滚不会影响它。