我在正在使用的其中一个应用程序中使用Spring和Hibernate,但是在处理事务时遇到了问题。
我有一个服务类,该类从数据库中加载一些实体,修改它们的某些值,然后(当所有内容都有效时)将这些更改提交给数据库。如果新值无效(我只能在设置新值之后检查),但我不想保留更改。为了防止Spring / Hibernate保存更改,我在方法中抛出异常。但是,这导致以下错误:
Could not commit JPA transaction: Transaction marked as rollbackOnly
这是服务:
@Service class MyService { @Transactional(rollbackFor = MyCustomException.class) public void doSth() throws MyCustomException { //load entities from database //modify some of their values //check if they are valid if(invalid) { //if they arent valid, throw an exception throw new MyCustomException(); } } }
这就是我调用它的方式:
class ServiceUser { @Autowired private MyService myService; public void method() { try { myService.doSth(); } catch (MyCustomException e) { // ... } } }
我希望发生的事情:对数据库没有任何更改,并且用户看不到任何异常。
发生的情况:没有对数据库进行任何更改,但应用程序崩溃并显示以下信息:
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
正确地将事务设置为rollbackOnly,但是为什么回滚会因异常而崩溃?
我的猜测是,这ServiceUser.method()本身就是事务性的。不应该这样 这就是原因。
ServiceUser.method()
调用ServiceUser.method()方法时,会发生以下情况:
现在,如果ServiceUser.method()不是事务性的,将发生以下情况: