Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query ------------ 關於mysql事物回滾的方法


關於我出現問題所在:

# 首先是在Dao中
@Modifying
@Query(value = "delete from user_role where uid in (SELECT uid from user_info where username = ?1)", nativeQuery = true)
Integer deleterUserRoleTableByName(String roleName);
# test(springboot 已經注入)
Integer integer = userInfoDao.deleterUserRoleTableByName("1");
System.out.println("integer = " + integer);
出現錯誤:

問題:沒有添加十五回滾,簡單的可以注解

@Modifying
@Transactional(rollbackFor = Exception.class)
@Query(value = "delete from user_role where uid in (SELECT uid from user_info where username = ?1)", nativeQuery = true)
Integer deleterUserRoleTableByName(String roleName);

結果:

好的,問題解決,現在是拓展筆記

-----------------------------------------------------------

上面因為我使用的是jpa方式,就是說DAO不需要實現,可以直接接口,如下圖:

所以只考慮注解,但是開發中好像事物回滾通常是在service中處理,這樣子,上面的方法拉到service也是可以使用,並且,還可以有別的方式,就是以前的方式。
以下方式學源於:https://blog.csdn.net/weixin_44299027/article/details/95231808
常用的三種注解

解決方案之一:在此方法@Transactional注解后面加上(rollbackFor = Exception.class)

解解決方案之二:@Transactional注解上不加rollbackFor這個屬性,在try...catch...的catch里寫上如何回滾。

下面代碼的三種方案都是正確的(第一種是在類級別的注解上,第二種是在方法級別的注解上,第三種是在捕獲異常后在catch里寫上)

事務場景中,拋出異常被catch后,如果需要回滾,一定要手動回滾事務。 
            
Positive example 1:
    @Service
    @Transactional(rollbackFor = Exception.class)
    public class UserServiceImpl implements UserService {
        @Override
        public void save(User user) {
            //some code
            //db operation
        }
    }
           
            
Positive example 2:
    @Service
    public class UserServiceImpl implements UserService {
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void save(User user) {
            //some code
            //db operation
        }
    }
        
            
Positive example 3:
    @Service
    public class UserServiceImpl implements UserService {
        @Autowired
        private DataSourceTransactionManager transactionManager;
 
        @Override
        @Transactional
        public void save(User user) {
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            // explicitly setting the transaction name is something that can only be done programmatically
            def.setName("SomeTxName");
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
 
            TransactionStatus status = transactionManager.getTransaction(def);
            try {
                // execute your business logic here
                //db operation
            } catch (Exception ex) {
                transactionManager.rollback(status);
                throw ex;
            }
        }
    }
解釋上述原因:
Spring框架的事務處理代碼默認地 只 在拋出運行時和unchecked exceptions時才標識事務回滾。 也就是說,當拋出個RuntimeException 或其子類的實例時,(Errors 也一樣 - 默認地 - 標識事務回滾。)從事務方法中拋出的Checked exceptions將 不 被標識進行事務回滾。
1、讓checked例外也回滾:在整個方法前加上 @Transactional(rollbackFor=Exception.class)
2、讓unchecked例外不回滾: @Transactional(notRollbackFor=RunTimeException.class)
3、不需要事務管理的(只查詢的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED)
注意: 如果異常被try{...}catch{...}了,事務就不回滾了,如果想讓事務回滾必須再往外拋try{...}catch{throw Exception}。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM