Home  >  Article  >  Java  >  Detailed introduction to @Transactional transaction rollback examples and source code in Spring (picture)

Detailed introduction to @Transactional transaction rollback examples and source code in Spring (picture)

黄舟
黄舟Original
2017-03-30 11:00:592107browse

1. Examples of usage scenarios

Before understanding how to use @Transactional, we must first know what @Transactional is used for. Here's an example: For example, there are many members in a department, which are stored in the department table and member table respectively. When deleting a department, assume that we delete the corresponding members by default. However, this situation may occur during execution. We delete the department first, and then delete the members. However, the department is deleted successfully, but an exception occurs when deleting the members. At this time, we hope that if the member deletion fails, the previously deleted departments will also be undelete. In this scenario, you can use @Transactional transaction rollback.

2. Checked exceptions and unchecked exceptions

The reason why everyone is clear about the concepts of checked exceptions and unchecked exceptions is because:

Spring uses declarative transaction processing , by default, if an unchecked exception occurs in the annotated Database Operation method, all database operations will rollback; if the exception that occurs is a checked exception, the database operation will still be submitted by default.

checked exception:

means invalid and cannot be predicted in the program. For example, invalid user input, file does not exist, network or database link error. These are all external reasons and cannot be controlled within the program.

Must be handled explicitly in code. For example, try-catch block processing, or add a throws description to the method to throw the exception to the upper layer of the call stack.

Inherits from java.lang.Exception (except java.lang.RuntimeException).

unchecked exception:

indicates an error and a logical error in the program. Is a subclass of RuntimeException, such as IllegalArgumentException, NullPointerException and IllegalStateException.

There is no need to explicitly catch unchecked exceptions in the code for processing.

Inherits from java.lang.RuntimeException (and java.lang.RuntimeException inherits from java.lang.Exception).

Look at the exception structure diagram below, maybe the sense of hierarchy will be deeper:

Detailed introduction to @Transactional transaction rollback examples and source code in Spring (picture)

3. Usage examples of @Transactional

This example uses What is used is Eclipse+maven. Maven is only managed as a jar. Even those who don’t understand Maven can understand it.

3.1. Spring’s configuration file

must first configure the tx namespace as follows:

Detailed introduction to @Transactional transaction rollback examples and source code in Spring (picture)

In order to use transaction management based on @Transactional, the following configuration needs to be done in Spring:

<bean id="appTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:annotation-driven proxy-target-class="false" transaction-manager="appTransactionManager" />

The entire spring configuration file of the blogger:




       
     
        
            
               classpath:properties/*.properties
                
            
        
    

    
    
        
        
       
        
            ${jdbc_driverClassName}
        
        
            ${jdbc_url}
        
        
            ${jdbc_username}
        
        
            ${jdbc_password}
        
    

    <bean id="appTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:annotation-driven proxy-target-class="false" transaction-manager="appTransactionManager" />

    
    
        
    

    
    
        
          
        
        
    

    
    

3.2. Use @Transactional, add user in implement class method and add annotation

@Transactional(propagation=Propagation.REQUIRED)
public void addUser(User user) {
    userDao.addUser(user);
    String string  = null;
    if(string.equals("")) {
        int i = 0;
    }
}

I deliberately caused a null pointer exception in the above method, which will roll back things

3.3. Run Unit testClass

@Test  
public void addUserTest(){  
    User user = new User();
    user.setUserName("luoguohui1");
    user.setUserPassword("luoguohui1");
    userService.addUser(user);
}

It is found that it cannot be inserted, but if @Transactional is removed, that is, the code is as follows, although an exception occurs, there is still something in the database Add corresponding data:

Detailed introduction to @Transactional transaction rollback examples and source code in Spring (picture)

3.4. Source code download

The project for this article is getting started with mybatis (including example tutorials and source code) Modified on the basis of , this article contains the detailed process of database script and project construction.

4. Concepts that you must understand about @Transactional in Spring

@Transactional in Spring is based on the dynamic proxy mechanism, which provides a transparent transaction management mechanism that is convenient and quick to solve during development problems encountered.

General use is to use the following code to comment on methods or interfaces or classes :

@Transactional(propagation=Propagation.NOT_SUPPORTED)

Propagation supports 7 different propagation mechanisms:

REQUIRED: If a transaction exists, the current transaction is supported. If there is no transaction, start a new transaction.

SUPPORTS: If a transaction exists, support the current transaction. If there is no transaction, then non-transaction execution. But for transaction managers with transaction synchronization, PROPAGATION_SUPPORTS is slightly different from not using transactions.

NOT_SUPPORTED: Always execute non-transactionally and suspend any existing transactions.

REQUIRESNEW: Always start a new transaction. If a transaction already exists, the existing transaction is suspended.

MANDATORY: If a transaction already exists, the current transaction is supported. If there is not an active transaction, throws an exception.

NEVER: Always execute non-transactionally, if there is an active transaction, throw an exception

NESTED: If an active transaction exists, run in a nested transaction. If there is no active transaction, execute according to REQUIREDproperty.

The following are some things that need attention, you must read them, otherwise you will encounter various pitfalls, don’t say that the blogger did not remind you:

The following are some things that need to be paid attention to. You must read them. Otherwise, don’t say that the blogger didn’t remind you if you encounter various pitfalls. :

The following are some things that need to be paid attention to. You must read them. You must read it, otherwise don’t say that the blogger didn’t remind you if you encounter various pitfalls:

  • Add the @Transactional annotation where transaction management is required. The @Transactional annotation can be applied to interface definitions and interface methods, class definitions, and public methods of classes.

  • @Transactional annotation can only be applied to methods with public visibility. If you use the @Transactional annotation on a protected, private or package-visible method, it will not report an error, but the annotated method will not display the configured transaction settings.

  • Note that the mere appearance of the @Transactional annotation is not enough to enable transaction behavior, it is just a kind of metadata. Configuration elements must be used in the configuration file to truly enable transaction behavior.

  • Use the element's "proxy-target-class" attribute value to control whether an interface-based or class-based proxy is created. If the "proxy-target-class" attribute value is set to "true", then class-based proxying will work (this requires the CGLIB library cglib.jar to be in the CLASSPATH). If the "proxy-target-class" attribute value is set to "false" or this attribute is omitted, then the standard JDK interface-based proxy will be used.

  • The Spring team recommends using the @Transactional annotation on specific classes (or methods of classes), rather than on any interface to be implemented by the class. Using the @Transactional annotation on an interface will only take effect if you set up an interface-based proxy. Because annotations are not inheritable, this means that if you are using a class-based proxy, the transaction settings will not be recognized by the class-based proxy, and the object will not be recognized by the transaction proxy. Package.

  • @Transactional transaction is opened, or an interface-based or class-based proxy is created. Therefore, if a method in the same class calls another method that has a transaction, the transaction will not work.

The above is the detailed content of Detailed introduction to @Transactional transaction rollback examples and source code in Spring (picture). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn