【Spring】Spring的事务管理

发布时间:2024年01月08日

前言:

package com.aqiuo.service.impl;

import com.aqiuo.dao.AccountMapper;
import com.aqiuo.pojo.Account;
import com.aqiuo.service.AccountService;
import org.springframework.jdbc.core.JdbcTemplate;

import java.sql.Connection;
import java.sql.SQLException;

/**
 * 账户的业务层实现类,实现新增的两条数据
 *
 */
public class AccountServiceImpl implements AccountService {

    AccountMapper accountMapper;

    JdbcTemplate jdbcTemplate;

    public void setAccountMapper(AccountMapper accountMapper) {
        this.accountMapper = accountMapper;
    }

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public boolean pay(Integer money, Integer produce, Integer customer) throws SQLException {
        Connection connection=jdbcTemplate.getDataSource().getConnection();
        connection.setAutoCommit(false);
      try {
          accountMapper.addMoney(money, produce);
          accountMapper.subMoney(money, customer);
          connection.commit();
      }catch (Exception e){
          connection.rollback();
          e.printStackTrace();
      }finally {
          connection.close();
      }
        return false;
    }
}

Spring事务管理概述

事务管理的核心接口
  1. PlatformTransactionManager
    1. 该接口是Spring提供平台事务管理器,主要用于管理事务状态事务
      1. TransactionStatus getTransaction(TransactionDefinition definition):获取事务的状态信息
      2. void commit(TransactionStatus status):用于提交事务
      3. void rollback(TransactionStatus status):用于回滚事务
    2. 该接口并不了解具体实现类,常用如下
      1. org.springframework.jdbc.datasource.DateSourceTransactionManager:用于配置JDBC数据源的事务管理器
      2. org.springframework.orm.hibenate4.HibernateTransactionManager:用于配置Hibernate的事务管理器
      3. org.springframework.transaction.jta.JtaTransactionManager:用于配置全局事务管理器
  2. TransactionDefinition
    1. 该接口是事务定义的对象,该对象定义了事物的规则,并提供了获取事务相关信息的方法,如下::
      1. String getName()
      2. int getIsolationLevel():获取事务的隔离级别
      3. int getPropagationBehavior():获取事务的传播行为
      4. int getTimeout():获取事务的超时时间
      5. boolean isReadOnly(): 获取事务是否只读
    2. 事务的传播行为是指在同一个方法中,不同操作前后所用的事务。种类如下:

(用的一个DataSource)

属性名称

事务管理员

事务协调员

PROPAGATION_REQUIRED

REQUIRED

开启T

加入T

新建T

PROPAGATION_SUPPORTS

SUPPORTS

开启T

加入T

PROPAGATION_MANDATORY

MANDATORY

开启T

加入T

ERROR

PROPAGATION_REQUIRES_NEW

REQUIRES_NEW

开启T

新建T2

新建T2

PROPAGATION_NOT_SUPPORTED

NOT_SUPPORTED

开启T

PROPAGATION_NEVER

NEVER

开启T

ERROR

PROPAGATION_NESTED

NESTED

事务管理过程中,传播行为可以控制是否需要创建以及如何创建事务。

  1. TransactionStatus
    1. 该接口是事物的状态,描述了某一时间点上事物的状态信息
      1. void flush()
      2. boolean hasSavepoint()
      3. boolean isCompleted()
      4. boolean isNewTransaction()
      5. boolean isRollbackOnly()
      6. void setRollbackOnly()

声明式事务管理

基于XML方式的声明式事务

Spring2.0以后,提供了tx命名空间来配置事务。tx命名空间下提供了元素来配置事务的通知。

当使用元素配置事务增强后,可以编写AOP配置,让Spring自动对目标生成代理

元素的属性

name

该属性为必选属性,指定了与事务属性相关的方法名,其属性支持通配符,例如:'get* '

propagation

用于指定事务的传播行为,默认值是REQUIRED

isolation

用于指定事务的隔离级别,默认为DEFAULT

read-only

用于指定事务是否只读,默认为false

timeout

用于指定事务超时的时间,默认为-1,即永不超时

rollback-for

用于指定触发事务回滚的异常类

no-rollback-for

用于指定不触发事务回滚的异常类

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
            xmlns:tx="http://www.springframework.org/schema/tx"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd 
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd 
              http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd  " > 
        <!-- 配置数据源 -->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <!-- 数据库驱动 -->
            <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
            <!-- 数据库的连接路径 -->
            <property name="url" value="jdbc:mysql://localhost:3306/spring"></property>
            <!-- 连接数据库的用户名 -->
            <property name="username" value="root"></property>
            <!-- 连接数据库的密码 -->
            <property name="password" value="3.14159265358"></property>
            
        </bean>
        <!-- 配置jdbcTemplate -->
        <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
            <property name="dataSource" ref="dataSource"></property>
        </bean>
    
        <!-- 注入 -->
        <bean id="accountDao" class="com.aqiuo.jdbc.AccountDaoImpl">
            <property name="jdbcTemplate" ref="jdbcTemplate"></property>
        </bean>
        
        <!-- 事务管理器,依赖于数据源 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        
        <!-- 编写事务通知,对事务进行增强 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"></tx:method>
            </tx:attributes>
        </tx:advice>
        
        <!-- 编写AOP,让Spring自动对目标生成代理,需要AspectJ的表达式 -->
        <aop:config>
            <aop:pointcut expression="execution(* com.aqiuo.*.*.*(..))" id="txPointCut"></aop:pointcut>
            <!-- 切面,将切入点与通知整合 -->
            <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"></aop:advisor>
        </aop:config>
     
         
</beans>

基于Annotation方式的声明式事务

Spring的声明式事务管理通过注解非常简单

步骤:

  1. 在Spring容器中注册事务注解驱动,代码如下

<tx:annotation-driver transaction-manager="transactionManager" />

  1. 在需要使用事务的SpringBean类(对类中所有方法有效)或Bean类上的方法(对该方法有效)上添加注解@Transactional

@Transactional可配置的参数

value

用于指定事务管理器

transactionManager

指定事务的限定符值,同value

isolation

指定事务的隔离级别

noRollbackFor

指定遇到特定异常时强制不会滚事务

noRollBackForClassName

指定遇到特定的多个异常时强制不会滚事务,属性值可以指定多个异常类名

propagation

用于指定事务的传播行为

read-only

用于指定事务是否只读

rollback-For

指定遇到特定异常时强制回滚事务

rollbackForClassName

指定遇到特定的多个异常时强制回滚事务,属性值可以指定多个异常类名

time

指定事务的超时时长

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
            xmlns:tx="http://www.springframework.org/schema/tx"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd 
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd 
              http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd  " > 
        <!-- 配置数据源 -->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <!-- 数据库驱动 -->
            <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
            <!-- 数据库的连接路径 -->
            <property name="url" value="jdbc:mysql://localhost:3306/spring"></property>
            <!-- 连接数据库的用户名 -->
            <property name="username" value="root"></property>
            <!-- 连接数据库的密码 -->
            <property name="password" value="3.14159265358"></property>
            
        </bean>
        <!-- 配置jdbcTemplate -->
        <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
            <property name="dataSource" ref="dataSource"></property>
        </bean>
    
        <!-- 注入 -->
        <bean id="accountDao" class="com.aqiuo.jdbc.anno.AccountDaoImpl">
            <property name="jdbcTemplate" ref="jdbcTemplate"></property>
        </bean>
        
        <!-- 事务管理器,依赖于数据源 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        
        <tx:annotation-driven transaction-manager="transactionManager" />
    
    
     
         
</beans>

注意:

  • 在实际开发中。事务的配置信息通常是在Spring的配置文件中完成的,而在业务层上只需要使用@Transactional注解即可。
  • 不需要配置@Transactional注解的属性

总结:

1.配置文件方式:

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="find*" isolation="DEFAULT"/>
        <tx:method name="pay" isolation="DEFAULT"></tx:method>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:advisor advice-ref="txAdvice" pointcut="execution(public * com.aqiuo.service.impl.AccountServiceImpl.*(..))"></aop:advisor>
</aop:config>

2.配置文件+注解:

<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

3.纯注解方式:

@EnableTransactionManager @Transactional

文章来源:https://blog.csdn.net/m0_62645012/article/details/135468374
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。