处理异常时保存不起作用

Joã*_*hin 5 java hibernate spring-data spring-boot

我面临着一种情况,我什至找不到调试方法。

我有以下spring-data存储库:

集成日志库

public interface IntegrationLogRepository extends PagingAndSortingRepository<IntegrationLog, Long> {

}
Run Code Online (Sandbox Code Playgroud)

Foo存储库

public interface FooRepository extends PagingAndSortingRepository<Foo, Long> {

}
Run Code Online (Sandbox Code Playgroud)

根据我的业务逻辑,我有如下内容:

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);
}
Run Code Online (Sandbox Code Playgroud)

当集成运行良好时,将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'
Run Code Online (Sandbox Code Playgroud)

1.5.15.RELEASE在 Spring Boot 、Java1.7和 WebLogic上运行12.1.3

谢谢!

Ren*_*407 8

引发的异常还会回滚集成日志保存。如果你想保存日志,你必须在保存时给它一个单独的事务。

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

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

在您的企业中替换

finally {
    integrationLogRepository.save(log);
}
Run Code Online (Sandbox Code Playgroud)

finally {
    integrationLogService.save(log);
}
Run Code Online (Sandbox Code Playgroud)

编辑

为什么@Transactional(propagation = Propagation.NOT_SUPPORTED)业务层的设置有效?

为了理解它为什么起作用,我们需要首先看看当一个人save在 spring 中调用使用org.springframework.data.repository.CrudRepository.

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

@Transactional
public <S extends T> S save(S entity)
Run Code Online (Sandbox Code Playgroud)

@Transactional需要默认传播。

Propagation propagation() default Propagation.REQUIRED;
Run Code Online (Sandbox Code Playgroud)

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

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