一尘不染

处理异常时,保存不起作用

spring-boot

我面临着无法找到调试方法的情况。

我有以下spring-data存储库:

集成日志存储库

public interface IntegrationLogRepository extends PagingAndSortingRepository<IntegrationLog, Long> {

}

Foo仓库

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);
}

集成运行良好时,将logOK状态一起保存。一切安好。但是当我有例外时,出于某种原因integrationLogRepository.save(log)什么也不会做。我什么也没什么意思:没有引发异常,并且我看不到任何在WebLogic控制台上执行的hibernate查询。日志未保留…

为什么会这样?

以下是我的依赖项:

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'

在Spring Boot 1.5.15.RELEASE,Java 1.7和WebLogic上运行12.1.3

谢谢!


阅读 359

收藏
2020-05-30

共1个答案

一尘不染

引发的异常也会回滚集成日志保存。如果要保存日志,则保存时必须给它单独的事务。

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

@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

Spring尝试确定TransactionAttribute方法和targetClass上的。对于method save和class
CrudRepository,简而言之,它没有找到任何东西。Spring使用SimpleJpaRepository的默认实现CrudRepository,如果没有在您的上找到任何事务属性,它将使用中指定的事务属性SimpleJpaRepository

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

默认传播@Transactional是必需的。

Propagation propagation() default Propagation.REQUIRED;

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

从上面的文档中可以看到,如果未指定任何事务,它将创建一个新事务。因此,当您将业务层上的事务设置为NOT_SUPPORTED(非事务执行)时,实际事务CrudRepository确实创建了它自己的事务,这意味着回滚不会影响它。

2020-05-30