处理异常时,保存不起作用 [英] Saving does not work when exception is handled

查看:176
本文介绍了处理异常时,保存不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm facing a situation I can't even find a way to debug.

我有以下spring-data存储库:

IntegrationLogRepository

public interface IntegrationLogRepository extends PagingAndSortingRepository<IntegrationLog, Long> {

}

FooRepository

public interface FooRepository extends PagingAndSortingRepository<Foo, Long> {

}

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

And on my business logic I have something like the following:

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控制台上执行的休眠查询.日志不持久...

When the integrations runs fine, the log is saved with the OK status. Everything is fine. But when I have an exception, for some reason integrationLogRepository.save(log) doesn't do nothing. I mean nothing NOTHING: No exception is thrown and I can't see any hibernate query being executed on my WebLogic console. The log is not persisted...

为什么会这样?

以下是我的依赖项:

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上运行.

Running on Spring Boot 1.5.15.RELEASE, Java 1.7 and WebLogic 12.1.3.

谢谢!

推荐答案

引发的异常也回滚了集成日志保存. 如果要保存日志,则保存时必须给它单独进行事务处理.

The exception that was thrown is also rolling back the integration log save. If you want to have the log saved, you have to give it a separate transaction when saving.

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

Abstract the log repository to a service and on the service method that saves the log add the transaction that creates a new transaction.

@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)起作用?

Why setting @Transactional(propagation = Propagation.NOT_SUPPORTED) on the business layer worked?

要了解其工作原理,我们首先需要看一下在春季使用org.springframework.data.repository.CrudRepository的存储库中调用save时会发生什么.

To understand why it worked, we need to first look at what happens when one calls save on a repository in spring that uses org.springframework.data.repository.CrudRepository.

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

Spring tries to determine the TransactionAttribute's on the method and targetClass. For the method save and class CrudRepository, in short it did not find any. Spring uses SimpleJpaRepository as the default implementation of the CrudRepository, if it did not find any transactional attributes on yours it will use the one specified in SimpleJpaRepository.

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

@Transactional上的默认传播是必需的.

The default propagation on @Transactional is required.

Propagation propagation() default Propagation.REQUIRED;

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

Support a current transaction, create a new one if none exists.

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

As you can see from the documentation above, if no transaction is specified it will create a new one. So when you set the transaction on the business layer to NOT_SUPPORTED (Execute non-transactionally), the actual CrudRepository did create it's own transaction which means the rollback would not affect it.

这篇关于处理异常时,保存不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆