Spring declarative transaction transaction manager transaction propagation behavior detailed introduction beginners must see

Declarative transaction

1. Introduction to declarative transactions

  1. Before you need to write a transaction through complex programming, now you only need to tell Spring which method is the transaction method, and Spring can automatically control the transaction

  2. Transaction method: The operations in the method meet the four characteristics of atomicity and other transactions (either all are executed or not executed)

  3. The transaction manager DataSourceTransactionManager in Spring can perform transaction control when the target method is running

2. Steps to use declarative transaction

  1. Use c3p0 to connect to the database

(1) Create c3p0.properties file in src directory

jdbc.username=root
jdbc.password=root
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/tx?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT
jdbc.driverClass=com.mysql.jdbc.Driver

(2) Configuration in xml

<context:property-placeholder location="classpath:c3p0.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
   
   <property name="user" value="${jdbc.username}"></property> 
   <property name="password" value="${jdbc.password}"></property>
   <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
   <property name="driverClass" value="${jdbc.driverClass}"></property>
   
</bean>
</beans>

(3) Test

   @org.junit.Test
   public void test() throws SQLException {
    
    
       ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
       DataSource dataSource = (DataSource)ioc.getBean("dataSource");
       System.out.println(dataSource.getConnection());
       //com.mchange.v2.c3p0.impl.NewProxyConnection@7d68ef40
   }

  1. Use JdbcTemplate to operate the database

(1) Guide package

Insert picture description here

(2) Write configuration

There is a parameterized constructor JdbcTemplate (DataSource dataSource) in
JdbcTemplate ; it is necessary to create a JdbcTemplate object to operate the database, in order not to go to the new object, register it in the container

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <!-- 引用容器中已经创建好的使用c3p0连接数据库的dataSource对象 -->
    <constructor-arg name="dataSource" ref="dataSource"></constructor-arg>
</bean>

(3) Test

   @org.junit.Test
   public void test2() {
    
    
       //将book表中book_name为book01的书的price修改为50
       ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
       JdbcTemplate jdbcTemplate = (JdbcTemplate)ioc.getBean("jdbcTemplate");
       String sql = "UPDATE book SET price=? WHERE book_name=?";
       int update = jdbcTemplate.update(sql, 50, "book01");
       System.out.println("受影响的行数:" + update);
       //受影响的行数:1
   }

  1. Configure transaction manager (transaction aspect)

(1) Guide package

Insert picture description here

(2) Written in xml

Insert picture description here

  1. Add @Transactional annotation to transaction method

(1) Create BookDao

@Service
public class BookDao {
    
    
   
   @Autowired
   JdbcTemplate jdbcTemplate;
   
   //修改账户的余额
   public void updateBalance(String username, int price) {
    
    
       String sql = "UPDATE account SET balance=balance-? WHERE username=?";
       jdbcTemplate.update(sql, price, username);
   }
   
   //修改图书的库存
   public void updateStock(int stock, String isbn) {
    
    
       String sql = "UPDATE book_stock SET stock=? WHERE isbn=?";
       jdbcTemplate.update(sql, stock, isbn);
   }
}

(2) Create BookService

@Service
public class BookService {
    
    
   
   @Autowired
   BookDao bookDao;
   
   //事务方法
   @Transactional
   public void update(String username, int price, String isbn, int stock) {
    
    
       //修改余额
       bookDao.updateBalance(username, price);
       //修改库存
       bookDao.updateStock(stock, isbn);
       int i = 10 / 0; //出现算术异常、事务方法中的两个操作均无法完成(回滚)
   }
}

3. Transaction details

The following are the attributes in the @Transactional annotation

  1. timeout
    timeout setting, int type, if the execution of the transaction method exceeds the specified duration, if it does not end, it will terminate and roll back, in seconds

用法:@Transactional(timeout=3)

  1. readOnly is
    set as a read-only transaction, boolean type, can speed up the query, only the transaction method can be used for query operations, if there is a modification operation, an error will be reported

用法:@Transactional(readOnly=true)

  1. noRollbackFor / rollbackFor
    noRollbackFor: set some abnormal transactions that were originally rolled back may not be rolled back
    rollbackFor: set some abnormal transactions
    that were originally not rolled back to let them roll back Both are of class[] type

Exception classification:
Runtime exception: can not be processed at compile time, and all are rolled back by default.
Compile time exception: must be processed at compile time (try-catch, throws), and the default is not rolled back

用法:@Transactional(noRollbackFor={NullPointerException.class, xxx.class})

  1. isolation
    isolation level transaction, Isolation type

usage:

Insert picture description here

Four, affairs spread behavior

  1. Introduction
    If there are multiple transactions nested, that is, the transaction method is called in the transaction method, if one of the transactions is abnormal, which of these nested transactions will be rolled back with it, and which will not be rolled back

  2. Instructions

Insert picture description here

  1. Communication behavior classification

Insert picture description here

如:
		(1) 使用了REQUIRED属性的事务方法如果嵌套在一个大的事务方法中,则二者属于同一个			   事务线上,一个失败,另一个也跟着回滚

		(2) 使用了REQUIRED_NEW属性的事务方法如果嵌套在一个大的事务方法中,则二者的事				务相互独立,一个失败,另一个不受影响(不会回滚)
  1. Graphical communication behavior

In the transaction method MulTx() in the figure below, two transaction methods checkout() and updatePrice() are called;
discuss the case of two nested transaction methods using attributes of different propagation behaviors:

Insert picture description here

Insert picture description here

  1. important point

(1) The use of attributes such as @Transactional(timeout=3) for the nested transaction method will not affect the entire transaction, and these attributes must be used in the large transaction that nests it to affect the entire transaction

(2) If the transaction methods of this class are nested in the transaction methods of this class, they belong to the same transaction

Five, transaction control using xml configuration

  1. Configure transaction manager (transaction aspect)
	 <!-- 
	 	基于xml配置的事务;依赖tx名称空间和aop名称空间
	 		1)、配置事务管理器(事务切面)
	    	2)、配置出事务方法
			3)、告诉Spring哪些方法是事务方法,事务切面按照给定的切入点表达式去切入事务方法
	  -->
	 
	 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	 	<property name="dataSource" ref="dataSource"></property>
	 </bean>

	 <!-- 事务切面按照给定的切入点表达式去切入事务方法 -->
	 <aop:config>
	 	<!-- 指明要切入哪些方法,但这些方法不一定使用事务 -->
	 	<aop:pointcut expression="execution(* com.atguigu.ser*.*.*(..))" id="txPoint"/>
	 	<!-- advice-ref指向配置事务管理器 -->
	 	<aop:advisor advice-ref="myAdvice" pointcut-ref="txPoint"/>
	 </aop:config>
	 
	 <!--  
	 	  配置事务管理器
	 	 transaction-manager="transactionManager":指定是配置哪个事务管理器;
	 -->
	 <tx:advice id="myAdvice" transaction-manager="transactionManager">
	 		<!--事务属性  -->
	 		<tx:attributes>
	 			<!-- 指明切入点表达式中的哪些方法是事务方法,-->
	 			<tx:method name="*"/> <!-- 所有方法都加事务 -->
	 			<tx:method name="checkout" propagation="REQUIRED" timeout="-1"/>
	 			<tx:method name="get*" read-only="true"/>
	 		</tx:attributes>
	 </tx:advice>

Guess you like

Origin blog.csdn.net/weixin_49343190/article/details/109772917