我面临着无法找到调试方法的情况。
我有以下spring-data存储库:
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); }
集成运行良好时,将log与OK状态一起保存。一切安好。但是当我有例外时,出于某种原因integrationLogRepository.save(log)什么也不会做。我什么也没什么意思:没有引发异常,并且我看不到任何在WebLogic控制台上执行的hibernate查询。日志未保留…
log
OK
integrationLogRepository.save(log)
为什么会这样?
以下是我的依赖项:
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.5.15.RELEASE
1.7
12.1.3
谢谢!
引发的异常也会回滚集成日志保存。如果要保存日志,则保存时必须给它单独的事务。
将日志存储库抽象到服务,然后在保存日志的服务方法上添加创建新事务的事务。
@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)在业务层进行设置有效?
@Transactional(propagation = Propagation.NOT_SUPPORTED)
要了解其工作原理,我们首先需要看一下save在spring人们调用一个使用的存储库时会发生什么org.springframework.data.repository.CrudRepository。
save
org.springframework.data.repository.CrudRepository
Spring尝试确定TransactionAttribute方法和targetClass上的。对于method save和class CrudRepository,简而言之,它没有找到任何东西。Spring使用SimpleJpaRepository的默认实现CrudRepository,如果没有在您的上找到任何事务属性,它将使用中指定的事务属性SimpleJpaRepository。
TransactionAttribute
CrudRepository
SimpleJpaRepository
@Transactional public <S extends T> S save(S entity)
默认传播@Transactional是必需的。
@Transactional
Propagation propagation() default Propagation.REQUIRED;
支持当前事务,如果不存在则创建一个新事务。
从上面的文档中可以看到,如果未指定任何事务,它将创建一个新事务。因此,当您将业务层上的事务设置为NOT_SUPPORTED(非事务执行)时,实际事务CrudRepository确实创建了它自己的事务,这意味着回滚不会影响它。
NOT_SUPPORTED