In the @Transactional transaction scenario, after the exception is thrown and caught, if you need to roll back, you must manually roll back the transaction

In a transaction scenario, after an exception is thrown and caught, if a rollback is required, the transaction must be rolled back manually.


@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) {
    
    
                //手动回滚事务
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw ex;
            }
        }

By default, the Spring transaction framework only rolls back the transaction when RuntimeException and unchecked exceptions are thrown (Errors default - transaction rollback), but the transaction will not be rolled back when Checked exceptions are thrown.

If we want to change this default, we can set it according to the scene:

Also rollback transactions when checked exceptions are thrown: @Transactional(rollbackFor=Exception.class)
Do not rollback transactions when unchecked exceptions are thrown: @Transactional(notRollbackFor=RunTimeException.class)
No transaction management is required: @Transactional(propagation=Propagation. NOT_SUPPORTED)
Note: If the exception is caught by try{}catch{}, the transaction will not be rolled back. If you want the transaction to roll back, you must throw try{}catch{throw Exception}.

The suggestion of the Spring team is that you use the @Transactional annotation on a concrete class (or class method), not on any interface that the class implements. You can of course use the @Transactional annotation on interfaces, but this will only work if you set up an interface-based proxy. Because annotations are not inherited, this means that if you are using class-based proxies, transaction settings will not be recognized by class-based proxies, and objects will not be wrapped by transaction proxies (will be validated for serious). Therefore, please take the advice of the Spring team and use the @Transactional annotation on concrete classes.
The @Transactional annotation identifies the method, and the processing process is as simple as possible. Especially for transaction methods with locks, it is best not to put them in the transaction if they can not be placed in the transaction. Regular database query operations can be performed before the transaction, and operations such as adding, deleting, modifying, and locking queries can be performed within the transaction.

Guess you like

Origin blog.csdn.net/god_sword_/article/details/129291879