[Turn] The use of spring transactions four [the use and rollback of annotations]

 

The use of annotations

       @Transactional can only be applied to public methods. For other non-public methods, if @Transactional is marked, no error will be reported, but the method has no transaction function.

Spring uses declarative transaction processing. By default, if the annotated database If an unchecked exception occurs in the operation method, all database operations will be rolledback; if the exception that occurs is a checked exception, the database operation will still be submitted by default.
This default behavior can be changed.

Use the noRollbackFor and rollbackFor attributes annotated with @Transactional

For example: @Transactional( rollbackFor=Exception.class ) can make the database operation rollback when a checked exception occurs, and @Transactional( noRollbackFor=RuntimeException.class ) can also submit the database operation when an unchecked exception occurs.

You can also use the noRollbackForClassName , rollbackForClassName properties to specify a String array of exception class names to change the default behavior.


 
Transaction management is not required when reading data in the database. In this case, the propagation behavior of the transaction can be used to tell Spring that the transaction does not need to be opened,
such as: @Transactional( propagation = Propagation.NOT_SUPPORTED ).

The propagation behaviors of transactions are:

1.           REQUIRED: Indicates that the business method needs to be processed in a transaction. If the business method is already in a transaction when it is executed, join the transaction, otherwise restart a transaction. This is also the default transaction propagation behavior; 2.           NOT_SUPPORTED: declares that the business method does not need a transaction. If the business method is already in a transaction when it is executed, the transaction is suspended, and after the method is executed, the transaction resumes; 3. REQUIRES_NEW: Indicates that the business method needs to be performed in a separate transaction. If the business method is already in a transaction, the transaction is suspended and a transaction is restarted to execute the business method. After the business method is executed, the original transaction 4. MANDATORY : This attribute specifies that the business method can only be performed in an existing transaction, and the business method cannot initiate its own transaction; if the business method is not performed in an existing transaction, the container will throw an exception; 5. SUPPORTS: This attribute specifies that if the business method is performed in an existing transaction, the transaction will be added; otherwise, the business method will be performed in an environment without a transaction; 6. NEVER: The specified business method cannot be performed in a transaction . If the business method is executed in a transaction, the container will throw an exception; 

 









7. NESTED: This attribute specifies that if the business method is executed in an existing transaction, the business method will be performed in a nested transaction; otherwise, it will be treated as REQUEIRED. It uses a single transaction, which can have multiple rollback points. The rollback of the inner transaction has no effect on the outer transaction, but the rollback of the outer transaction will cause the rollback of the inner transaction. This behavior is only valid for DataSourceTransactionManager.

 

The isolation level of the transaction

  Use the Isolation property of @Transactional to specify the isolation level of the transaction. But the isolation level of the transaction is implemented by the underlying database, not by Spring.

1. READ_UNCOMMITTED: Dirty read, non-repeatable read and phantom read problems

will occur; 2. READ_COMMITTED: Non-repeatable read and phantom read problems will occur;

3. REPEATABLE_READ: Phantom read problems will occur;

4. SERIALIZABLE: Serialization, no The above problem will occur.

  General databases provide the READ_COMMITTED isolation level by default, such as sqlserver2000; Mysql provides REPEATABLE_READ by default.

All optional properties of @Transactional are as follows:
Property Type Default Value Description
propagation Propagation enumeration REQUIRED Transaction propagation properties 
isolation isolation enumeration DEFAULT transaction isolation level
readOnly boolean false read-only
timeout int -1 timeout (seconds)
rollbackFor Class[] {} the exception class to be rolled back
rollbackForClassName String[] {} the exception class name to be rolled back
noRollbackFor Class[ ] {} Exception class that does not need to be rolled back
noRollbackForClassName String[] {} Exception class name that does not need to be rolled back



//Transaction propagation property
    @Transactional(propagation=Propagation.REQUIRED) //If there is a transaction, then join the transaction, if not Create a new one (without writing)
    @Transactional(propagation=Propagation.NOT_SUPPORTED) //The container does not open transactions for this method
    @Transactional(propagation=Propagation.REQUIRES_NEW) //Regardless of whether there is a transaction, create a new transaction, the original one is suspended, the new one is executed, and the old transaction is continued
    @Transactional(propagation=Propagation.MANDATORY) //Must Execute in an existing transaction, otherwise throw an exception
    @Transactional(propagation=Propagation.NEVER) //Must be executed in an existing transaction, otherwise throw an exception (opposite to Propagation.MANDATORY)
    @Transactional(propagation=Propagation .SUPPORTS) //If other beans call this method and declare transactions in other beans, then use transactions. If other beans do not declare transactions, then do not use transactions.
    
 
    @Transactional(propagation=Propagation.NESTED)     @Transactional (propagation = Propagation.REQUIRED,readOnly=true) //readOnly=true read-only, cannot be updated, delete     @Transactional (propagation = Propagation.REQUIRED, timeout=30)//Set the timeout     @Transactional (propagation = Propagation.REQUIRED, isolation=Isolation .DEFAULT)//Set the database isolation level and use the spring transaction manager, which is responsible for opening, committing, and rolling back the database. 
 
 




By default, a runtime exception (throw new RuntimeException("Comment");) will be rolled back, that is, when an unchecked exception is
encountered ; ");) will not roll back, that is, when encountering a checked exception (that is, an exception that is not thrown at runtime, the exception that the compiler will check is called a checked exception or a checked exception), we need to specify a way to Let the transaction roll back, as follows:
@Transactional( rollbackFor=Exception.class ) //Specify rollback, rollback when an Exception is encountered
    public void methodName() {
       throw new Exception("Comment");
       
    }
@Transactional(noRollbackFor= Exception.class)//Specify not to roll back, it will roll back when encountering runtime exception (throw new RuntimeException("comment");)
    public ItimDaoImpl getItemDaoImpl() {
        throw new RuntimeException("comment");
    } 

 

 

2. Rollback

In Spring's configuration file, if the defaultAutoCommit of the data source is set to True, then if the method catches an exception, the transaction will not be rolled back. If the exception is not caught by itself, the transaction will be rolled back. For
example, the configuration file There is this record:

 

  1. <beanid="dataSource"class="xxx">    
  2.    <propertyname="xxx"value="xxx"/>    
  3.    <propertyname="xxx"value="xxx"/>    
  4.                      ....  
  5.      <propertyname="defaultAutoCommit"value="true"/>     
  6. </bean>  


So now there are two cases
Case 1: If the exception is not manually caught in the program

 

 

  1. @Transactional(rollbackFor = { Exception.class })  
  2. publicvoid test() throws Exception {   
  3.      doDbStuff1();  
  4.      doDbStuff2(); //If this method of operating the database will throw an exception, now the operation of the method doDbStuff1() on the database will be rolled back.  
  5. }  


Case 2: If you catch the exception yourself in the program

 

 

  1. @Transactional(rollbackFor = { Exception.class })  
  2. publicvoid test() {   
  3.      try {  
  4.         doDbStuff1();  
  5.         doDbStuff2(); //If this method of operating the database will throw an exception, now the operation of the method doDbStuff1() on the database will not be rolled back.  
  6.      } catch (Exception e) {  
  7.            e.printStackTrace ();     
  8.      }  
  9. }  


Now what if we need to manually catch exceptions, and also want to rollback when exceptions are thrown?
The following is enough to manually roll back the transaction:

 

 

  1. @Transactional(rollbackFor = { Exception.class })  
  2. publicvoid test() {   
  3.      try {  
  4.         doDbStuff1();  
  5.         doDbStuff2();  
  6.      } catch (Exception e) {  
  7.           e.printStackTrace ();     
  8.           TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //That's it, after adding, if doDbStuff2() throws an exception, //doDbStuff1() will roll back  
  9.      }  
  10. }  

Guess you like

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