A few trifles about transaction management in spring

Keywords: PHP Spring Java JDBC Database

1. Transaction management in Spring

  • As an enterprise application framework, Spring defines an abstraction layer on top of different transaction management APIs. Application developers can use Spring's transaction management mechanism without knowing the underlying transaction management API.
  • Spring supports both programmatic and declarative transaction management.
  • Programming transaction management: Embedding transaction management code into business methods to control transaction submission and rollback. When managing transactions programmatically, additional transaction management code must be included in each transaction operation.
  • Declarative transaction management: In most cases, it is better than programmable transaction management. It separates transaction management code from business methods and implements transaction management in a declarative manner. Transaction management, as a cross-cutting concern, can be modularized by AOP method. Spring supports declarative transaction management through the Spring AOP framework.

2. Transaction Manager in Spring

  • Spring abstracts a set of transaction mechanisms from different transaction management APIs. Developers can take advantage of these transaction mechanisms without having to understand the underlying transaction APIs. With these transaction mechanisms, transaction management code can be independent of specific transaction technologies.
  • Spring's core transaction management abstraction is that Transaction Manager management encapsulates a set of technology-independent approaches. Whether using Spring's transaction management strategy (programmatic or declarative), a transaction manager is required.
  • Data Source Transaction Manager: In an application, only one data source needs to be processed and stored through JDBC.
  • JtaTransaction Manager: Transaction management with JTA on Java EES application server.
  • Hibernate Transaction Manager: Access databases using the Hibernate framework.
  • The transaction manager is declared in the Spring IOC container in the form of a common Bean.

    3. Managing transactions declaratively with transaction notifications

  • Transaction management is a cross-cutting concern.
  • To enable declarative transaction management in Spring 2.x, transaction notifications can be declared through elements defined in tx Schema. This Schema definition must be added to the root element beforehand.
  • After declaring a transaction notification, you need to associate it with the entry point. Since the transaction notification is declared outside the element, the index cannot directly associate with the entry point, so you must declare an enhancer notification in the element to associate with the entry point.
  • Since Spring AOP is a proxy-based approach, indexing can only enhance common methods. Therefore, only public methods can manage transactions through Spring AOP.
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
         <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <tx:advice id="bookShopTxAdvice" transaction-manager="transactionManager"></tx:advice>
    
    <aop:config>
        <aop:pointcut id="bookShopOperation" expression="execution(* *.BookShopService.*(..))"></aop:pointcut>
        <aop:advisor advice-ref="bookShopTxAdvice" pointcut-ref="bookShopOperation"/>
    </aop:config>

4. Annotate declarative management transactions with @Transactional

  • In addition to declaring transactions in Bean configuration files with pointcuts, notifications, and enhancers, Spring allows simple annotations of transaction methods with the @Transactional annotation.
  • To define a method as supporting transaction processing, you can add the @Transactional annotation to the method. According to Spring AOP based on proxy mechanism, only public methods can be labeled.
  • The @Transactional annotation can be added at the method or class level. When this annotation is applied to a class, all common methods in the class are defined to support transaction processing.
  • In the Bean configuration file, you only need to enable elements and specify a transaction processor for them.
  • If the name of the transaction processor is transactionManager, the transaction-manager attribute can be omitted from the element. This element automatically detects the transaction handler for that name.
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <context:component-scan base-package="com.desparado.service"></context:component-scan>
    
    <tx:annotation-driven/>

5. Transaction propagation properties

  • When a transaction method is invoked by another transaction method, it must specify how the transaction should propagate, for example, the method may continue to run in an existing transaction, or it may open a new transaction and run in its own transaction.
  • Transaction propagation behavior can be specified by transmission properties. Spring defines seven propagation behaviors.
Propagation attribute describe
REQUIRED If a transaction is running, the current method runs within the transaction. Otherwise, it starts a new transaction and runs within its own transaction.
REQUIRED_NEW The current method must start a new transaction and run it within its own transaction, and if a transaction is running, it should be suspended.
SUPPORTS If a transaction is running, the current method runs within the transaction, otherwise it may not be allowed in the transaction.
NOT_SUPPORTED The current method should not run in a transaction. If there is a running transaction, suspend it.
MANDATORY The current method must run within the transaction, and if there is no running transaction, an exception is thrown.
NEVER Current methods should not run in transactions, and if there are running transactions, run out of exceptions
NESTED If a transaction is running, the current method should run within the nested transaction of the transaction. Otherwise, a new transaction will be started and run within its own transaction.
  • Configuration of Transaction Propagation Properties
    Configure the properties in the @Transactional annotation
@Transactional(propagation=Propagation.REQUIRES_NEW)

You can configure it in xml

<tx:advice id="bookShopTxAdvice" transaction-manager="transactionManager">
    <tx:attributes>
          <tx:method name="purchase" propagation="REQUIRES_NEW"/>
    </tx:attributes>
</tx:advice>
    

6. Setting isolated transaction properties

  • When managing transactions declaratively with the @Transactional annotation, isolation levels can be set in the isolation attribute of @Transactional
@Transactional(propagation=Propagation.REQUIRES_NEW,isolation=Isolation.READ_COMMITTED)
  • In Spring 2.x transaction notifications, isolation levels can be specified in the < tx: method"element
<tx:advice id="bookShopTxAdvice" transaction-manager="transactionManager">
    <tx:attributes>
          <tx:method name="purchase" propagation="REQUIRES_NEW" 
              isolation="READ_COMMITTED"/>
    </tx:attributes>
</tx:advice>

7. Setting Rollback Transaction Properties

  • By default, only unchecked exceptions (Runtime Exception and Error type exceptions) cause transactions to roll back, and two unchecked exceptions do not.
  • The rollback rule of a transaction can be defined by the rollbackFor and noRollbackFor attributes of the @Transactional annotation, which are declared as Class [], so multiple exception classes can be specified for these two attributes.
    - rollbackFor: You must roll back when you encounter it.
    - noRollbackFor: A set of exception classes that must not roll when encountered

    @Transactional(propagation=Propagation.REQUIRED_NEW,
                  isolation=Isolation.READ_COMMITTED,
                  rollbackFor=(IOException.class,SQLException.class),
                  noRollbackFor=ArithmeticException.class)  
    public void purchase(String isbn,String username){}
  • In Spring 2.x transaction notifications, you can specify rollback rules in the < tx: method primitive species, separated by commas if there are more than one exception
<tx:advice id="bookShopTxAdvice" transaction-manager="transactionManager">
   <tx:attributes>
         <tx:method name="purchase" propagation="REQUIRES_NEW" 
             isolation="READ_COMMITTED"
             rollback-for="java.io.IOException,java.sql.SQLException" 
             no-rollback-for="java.lang,ArithmeticException"/>
   </tx:attributes>
</tx:advice>

8. Timeout and Read-Only Properties

  • Because transactions can acquire locks on rows and tables, long transactions take up resources and affect overall performance.
  • If a transaction only reads data without modification, the database engine can optimize the transaction.
  • Timeout transaction property: How long can a transaction last before a mandatory rollback. This prevents long-running transactions from taking up resources.
  • Read-only transaction property: This means that the transaction only reads the database but does not update the database, which helps the database engine optimize transactions.
  • Timeout and read-only attributes can be defined in the @Transactional annotation, and timeout attributes are in seconds.
@Transactional(propagation=Propagation.REQUIRED_NEW,
                isolation=Isolation.READ_COMMITTED,
                rollbackFor=(IOException.class,SQLException.class),
                noRollbackFor=ArithmeticException.class,
                readOnly=true,tomeout=30)  
public void purchase(String isbn,String username){}

- In Spring 2.x transaction notifications, timeout and read-only attributes can be specified in elements

<tx:advice id="bookShopTxAdvice" transaction-manager="transactionManager">
    <tx:attributes>
          <tx:method name="purchase" propagation="REQUIRES_NEW" 
              isolation="READ_COMMITTED"
              rollback-for="java.io.IOException,java.sql.SQLException" 
              no-rollback-for="java.lang,ArithmeticException"  
              read-only=true
              timeout=30/>
    </tx:attributes>
</tx:advice>

Posted by michaelpalmer7 on Thu, 30 May 2019 12:17:28 -0700