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

时间:2018-12-20 12:10:04

标签: java hibernate spring-boot spring-data

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

我有以下spring-data存储库:

IntegrationLogRepository

public interface IntegrationLogRepository extends PagingAndSortingRepository<IntegrationLog, Long> {

}

FooRepository

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'

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

谢谢!

1 个答案:

答案 0 :(得分:0)

引发的异常也回滚了集成日志保存。 如果要保存日志,则保存时必须单独进行交易。

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

@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的存储库中调用org.springframework.data.repository.CrudRepository时会发生什么。

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

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

需要在@Transactional上进行默认传播。

Propagation propagation() default Propagation.REQUIRED;
  

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

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