spring-data - @Transactional noRollbackFor EmptyResultDataAccessException.class 不起作用
问题描述
我想忽略异常并无论如何提交事务。但是,每次我得到一个错误。究竟是什么问题,我该如何解决?
@Transactional( noRollbackFor = EmptyResultDataAccessException.class )
public Foo foo( Foo foo, String barId ) {
Foo foo = fooRepository.save(foo)
deleteBarSilently(barId)
return foo ;
}
//@Transactional( noRollbackFor = EmptyResultDataAccessException.class )
private void deleteBarSilently( final String barId) {
try {
barRepository.deleteById( barId);
} catch ( final EmptyResultDataAccessException ignored ) {
System.out.println( ignored );
}
}
错误是:org.springframework.transaction.TransactionSystemException:无法提交 JPA 事务;嵌套异常是 javax.persistence.RollbackException:事务“回滚”,因为事务设置为 RollbackOnly。
异常是 EmptyResultDataAccessException
编辑:还尝试使用 try/catch 和没有和使用异常数组 @Transactional( noRollbackFor = {EmptyResultDataAccessException.class} ) 并使用完全限定的类名
没有捕获的日志
Application exception overridden by commit exception
org.springframework.dao.EmptyResultDataAccessException: No class com.bosch.bci.foundation.digitaltwin.repository.domain.ModelReference entity with id c16675da-f5ce-46b1-97e6-7eb6869940aa exists!
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.lambda$deleteById$0(SimpleJpaRepository.java:166) ~[spring-data-jpa-2.5.3.jar:2.5.3]
用 catch 记录只是
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction "rolled back" because transaction was set to RollbackOnly.
解决方案
noRollbackFor
需要一个 Throwable 子类数组,而不是您只传递一个类 ( EmptyResultDataAccessException
)
尝试更改为(注意表示数组的大括号“{”和“}”):
@Transactional( noRollbackFor = { EmptyResultDataAccessException.class })
更新
除非您全局EmptyResultDataAccessException
设置.RuntimeException
globalRollbackOnParticipationFailure=false
解决方案 1
第一个解决方案是实现你自己的barRepository.deleteById( barId)
,它不会抛出EmptyResultDataAccessException
例如
在您BarRepository
创建以下方法:
@Transactional
@Modifying
@Query("DELETE FROM Bar b WHERE b.id= :id")
void customDeleteById(Long id);
并在您的deleteBarSilently
删除中try catch
简单地拥有:
@Transactional
private void deleteBarSilently( final Long barId) {
barRepository.customDeleteById( barId);
}
解决方案 2
在第二个解决方案中,您可以将代码更改为以下以deleteBarSilently
在事务的外部运行,foo
因此当您点击它时,EmptyResultDataAccessException
不会try catch
发生回滚。
首先,您需要将您的方法与不同的服务分开(以便@Transactional
注释工作),比如说FooService
and BarService
,
食品服务
@Service
public class FooService {
@Autowired
private FooRepository fooRepository;
@Autowired
private BarService barService;
@Transactional
public Student foo( Foo foo, Long barId ) {
Foo savedFoo = fooRepository.save(foo);
barService.deleteBarSilently(barId);
return savedFoo ;
}
}
酒吧服务
注释@Transactional(propagation = Propagation.NOT_SUPPORTED)
将导致事务暂停的方法,在事务之外执行该方法的代码,然后恢复。
@Service
public class BarService {
@Autowired
private BarRepository barRepository;
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void deleteBarSilently( final Long barId) {
try {
barRepository.deleteById( barId);
} catch (EmptyResultDataAccessException exc) {
System.out.println(exc);
}
}
}
推荐阅读
- android - 无法检索用户个人资料
- angularjs - Camera Plugin 的前置摄像头在 Ionic 3 中无法正常工作
- angularjs - 在部分视图上使用 MVC 的日期范围选择器 AngularJS 问题
- python - Django CMS:在版本 3.5.2 中迁移 djangocms_table 时出现 BadMigrationError
- node.js - Webpack - NodeJS - 找不到模块:错误:无法解析“fs”
- jquery - Jquery在Office选择输入中追加
- typo3 - TYPO3 TCA 用户函数
- javascript - 在 expressjs mongoose 中发送带有页面渲染的 obj
- css - flex:1 属性中 css flex-box 和 react-native 之间的区别
- php - 错误 - 在 laravel 中从数据库中获取数据时找不到驱动程序