Comportamento de propagação de transações do gerenciador de transações declarativo Spring, introdução detalhada, os iniciantes devem ver

Transação declarativa

1. Introdução às transações declarativas

  1. Antes de precisar escrever uma transação por meio de programação complexa, agora você só precisa dizer ao Spring qual método é o método de transação, e o Spring pode controlar automaticamente a transação

  2. Método de transação: as operações no método atendem às quatro características de atomicidade e outras transações (todas são executadas ou não executadas)

  3. O gerenciador de transações DataSourceTransactionManager no Spring pode realizar o controle da transação quando o método de destino está sendo executado

Em segundo lugar, as etapas para usar transações declarativas

  1. Use c3p0 para se conectar ao banco de dados

(1) Crie o arquivo c3p0.properties no diretório src

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) Configuração em 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) Teste

   @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 para operar o banco de dados

(1) Pacote guia

Insira a descrição da imagem aqui

(2) Configuração de gravação

Existe um construtor JdbcTemplate parametrizado (DataSource dataSource) no
JdbcTemplate ; é necessário criar um objeto JdbcTemplate para operar o banco de dados, para não ir ao novo objeto, registre-o no container

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

(3) Teste

   @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 o gerenciador de transações (aspecto da transação)

(1) Pacote guia

Insira a descrição da imagem aqui

(2) Escrito em xml

Insira a descrição da imagem aqui

  1. Adicionar anotação @Transactional ao método de transação

(1) Criar 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) Criar 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. Detalhes da transação

A seguir estão os atributos na anotação @Transactional


  1. Configuração de tempo limite de tempo limite, tipo int, se a execução do método de transação exceder a duração especificada, se não terminar, será encerrado e revertido, em segundos

用法 : @Transactional (tempo limite = 3)

  1. readOnly é
    definido como uma transação somente leitura, tipo booleano, pode acelerar a consulta, apenas o método de transação pode ser usado para operações de consulta, se houver uma operação de modificação, um erro será relatado

用法 : @Transactional (readOnly = true)

  1. noRollbackFor / rollbackFor
    noRollbackFor: definir algumas transações anormais que foram originalmente revertidas não podem ser revertidas
    rollbackFor: definir algumas transações anormais
    que originalmente não foram revertidas para permitir que elas retrocedam Ambos são do tipo classe []

Classificação de
exceção: exceção de tempo de execução: não pode ser processado em tempo de compilação e todos são revertidos por padrão.
Exceção de tempo de compilação: deve ser processado em tempo de compilação (try-catch, throws), e o padrão não é revertido

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


  1. transação de nível de isolamento de isolamento, tipo de isolamento

uso:

Insira a descrição da imagem aqui

Quatro, casos espalham comportamento

  1. Introdução
    Se houver várias transações aninhadas, ou seja, o método de transação é chamado no método de transação, se uma das transações for anormal, quais dessas transações aninhadas serão revertidas com ela, e quais não

  2. Instruções

Insira a descrição da imagem aqui

  1. Classificação do comportamento de comunicação

Insira a descrição da imagem aqui

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

		(2) 使用了REQUIRED_NEW属性的事务方法如果嵌套在一个大的事务方法中,则二者的事				务相互独立,一个失败,另一个不受影响(不会回滚)
  1. Comportamento de comunicação gráfica

No método de transação MulTx () na figura abaixo, dois métodos de transação checkout () e updatePrice () são chamados;
discuta o caso de dois métodos de transação aninhados usando atributos de diferentes comportamentos de propagação:

Insira a descrição da imagem aqui

Insira a descrição da imagem aqui

  1. ponto importante

(1) O uso de atributos como @Transactional (tempo limite = 3) para o método de transação aninhada não afetará toda a transação, e esses atributos devem ser usados ​​na transação grande que o aninha para afetar toda a transação

(2) Se os métodos de transação desta classe estão aninhados nos métodos de transação desta classe, eles pertencem à mesma transação

Quinto, controle de transação usando configuração xml

  1. Configure o gerenciador de transações (aspecto da transação)
	 <!-- 
	 	基于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>

Acho que você gosta

Origin blog.csdn.net/weixin_49343190/article/details/109772917
Recomendado
Clasificación