Using @Transactional, the reason why you will not roll back when you throw an exception yourself

1. When you read this article, if the reader encounters this problem when integrating the three major frameworks of j2EE, it should be the following problem:
   
    I remember that when I encountered this problem at the time, it was because the database table , does not support transactions! If mysql does not support the storage engine, it will create the table as a MyISAM table, which is a non-transactional table. Generally modified to InnoDB.
 
    If you are interested in understanding the "engine=innodb" in mysql and the difference between "engine=innodb and engine=myisam", you can read this article, which may be helpful to readers: http://blog.sina. com.cn/s/blog_6ac4c6cb01018pb1.html
 
    Use one of the following statements to check the scalar type of the table: 
    SHOW TABLE STATUS LIKE 'tbl_name';
    SHOW CREATE TABLE tbl_name;
  Use the following statement to check the storage engine supported by the mysqld server: 
   
    SHOW ENGINES;
 
    You can also use the following statement to check the variable value related to the storage engine you are interested in: 

    SHOW VARIABLES LIKE 'have_%';

  For example, to determine whether the InnoDB storage engine is available, check the value of the have_innodb variable.
 
 
 2. If the reader is not in the above situation, please study the following paragraph:
----------------------------------- -------------------------------------------------- -------------
 
In recent test cases, we found such a phenomenon:

in the business code, there are the following two situations, such as:
throw new RuntimeException("xxxxxxxxxxxx"); transaction rollback throw
new Exception("xxxxxxxxxxxx"); transaction is not rolled back
 
Understand the transaction, perhaps because of the long time, I did not analyze the reason, so I checked the following information and wrote the following content for reference:
 
1). Spring's AOP, the declarative transaction management, defaults to rollback for unchecked exceptions. That is, by default, the RuntimeException() exception or its subclasses are rolled back; checked exceptions, that is, Exceptions that can be caught by try{} will not be rolled back, if the unchecked exception thrown by try-catch is not caught in the catch block If the transaction is explicitly rolled back by using the spring api by hard-coding the page, the transaction will not be rolled back. "Capture the exception, and do not explicitly commit the transaction in the catch block = swallow the exception alive". If you want to catch non-runtime exceptions, you need the following configuration:
Solutions:
1. Throw RuntimeException in the transaction-oriented class instead of throwing Exception.
2. Add rollback-for in txAdive and write your own exception in it, such as your own exception:

<tx:advice id="txAdvice" transaction-manager="transactionManager">
   <tx:attributes>
     <tx:method name="*" rollback-for="com.cn.untils.exception.XyzException"/>
   </tx:attributes>
 </tx:advice>
 
or
define an exception that will not roll

<tx:advice id ="txAdvice">
    <tx:attributes>
       <tx:method name="update*" no-rollback-for="IOException"/>
       <tx:method name="*"/>
    </tx:attributes>
 </ tx:advice>
 
2). Spring's transaction boundary starts before calling the business method. After the business method is executed, commit or rollback is executed (Spring default depends on whether a runtime exception is thrown).
 If a runtime exception is thrown and you If there is no catch in the business method, the transaction will be rolled back. 
 Generally, there is no need to catch exceptions in business methods. If you have to catch, you must throw a runtime exception after you have done the work you want to do (such as closing files, etc.), otherwise spring will commit your operation, which will generate dirty data. So your catch code is superfluous.
 
Such as:
try {  
    //bisiness logic code  
} catch(Exception e) {  
    //handle the exception  
}  
 It can be inferred from this that if a business method is wrapped in a whole in spring, the business method is equivalent to being out of the management of spring transactions, because there is no exception will be thrown from the business method! All are caught and swallowed, causing the spring exception to trigger the transaction rollback strategy to fail.
 However, if you use the spring api to explicitly roll back the transaction by hard-coding the page in the catch code block, it is not impossible to write this way.
 
 3). Annotation-based transaction:
 Transactional exception control, the default is Check Exception not to roll back, unCheck Exception to roll back
 If rollbackFor and noRollbackFor are configured and both use the same exception, then when the exception is encountered, it is still rolled back
 The configuration of rollbackFor and noRollbackFor may not cover all exceptions. For missing ones, check Exception will not be rolled back, and unCheck Exception will be rolled back.

This blog post is reprinted from: http://blog.sina.com.cn/s/blog_6ac4c6cb01018pbl.html

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326785657&siteId=291194637