天天看点

Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务

目录

  • 第一节 事务的隔离级别【回顾】
    • 特性:ACID
    • 隔离问题
    • 隔离级别--解决问题
    • mysql 事务操作--简单
    • mysql 事务操作--Savepoint
  • 第二节 Spring事务管理介绍
    • 2.1 Spring提供的事务jar包
    • 2.2 Jar包中的三个顶级接口
    • 2.3 PlatformTransactionManager 事务管理器
      • 导入以下jar包
      • 之前常用的两个事务管理器
    • 2.4 TransactionDefinition 事务定义
    • 2.5 TransactionStatus 事务状态
  • 第三节 转账案例:使用Spring管理事务
    • 3.1 环境搭建
      • 第一步:创建数据库表
      • 第二步:导入相关jar包
      • 第三步:Dao层代码编写
      • 第四步:Service层代码编写
      • 第五步:Spring的配置
      • 第六步:测试与效果
    • 3.2 手动管理事务【了解】
      • 1. 修改Service
      • 2. 修改spring的配置文件
      • 3. 测试与效果
    • 3.3 工厂bean生成代理:半自动
      • 1. service无需配置事务模板
      • 2. 修改spring的配置文件
      • 3. 测试与效果
    • 3.4 使用AOP配置事务【掌握】
      • 1. spring的配置
      • 2. 测试与结果
    • 3.5 使用注解配置事务
      • 1.spring的配置
      • 2. 测试与效果

第一节 事务的隔离级别【回顾】

  • 为什么有事务的隔离级别?
  • 解决多线程访问数据库的问题。
  • 一组业务操作,要么全部成功,要么全部不成功。

特性:ACID

  • 原子性:整体 【原子性是指事务包含的所有操作要么全部成功,要么全部失败】
  • 一致性:数据 【一个事务执行之前和执行之后都必须处于一致性状态】
  • 隔离性:并发 【对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。】
  • 持久性:结果 【持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的】

隔离问题

  • 脏读:一个事务读到另一个事务未提交的内容【读取未提交内容】

    在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其它级别好多少。

  • 不可重复读:一个事务读到另一个事务已提交的内容(insert)【读取提交内容】

    这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。

  • 虚读(幻读):一个事务读到另一个事务已提交的内容(update)

    这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。

  • Serializable(可串行化)

    这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

隔离级别–解决问题

  • read uncommittd,读未提交。存在3个问题。
  • read committed,读已提交。解决:脏读。存在2个问题。
  • repeatable read ,可重复读。解决:脏读、不可重复读。存在1个问题。
  • serializable,串行化。单事务。没有问题。
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务

mysql 事务操作–简单

  • ABCD(4个操作) 一个事务
Connection conn = null;
try{
  //1 获得连接
  conn = ...;
  //2 开启事务
  conn.setAutoCommit(false);//不要自动提交事务
  A
  B
  C
  D
  //3 提交事务
  conn.commit();
} catche(){
  //4 回滚事务
  conn.rollback();
}
           

mysql 事务操作–Savepoint

  • 需求:AB(必须),CD(可选)
Connection conn = null;
Savepoint savepoint = null;  //保存点,记录操作的当前位置,之后可以回滚到指定的位置。(可以回滚一部分)
try{
  //1 获得连接
  conn = ...;
  //2 开启事务
  conn.setAutoCommit(false);
  A
  B
  savepoint = conn.setSavepoint();//设置保存点
  C
  D
  //3 提交事务
  conn.commit();
} catche(){
  if(savepoint != null){   
  	 //CD异常
     //回滚到CD之前
     conn.rollback(savepoint);//如果保存点有值,回滚到记录的保存点,CD之前
     //提交了AB
     conn.commit();
  } else{
  	 //如果保存点没有值,直接回滚到A之前  
  	 //AB异常
     //回滚AB
     conn.rollback();
  }
}
           

第二节 Spring事务管理介绍

2.1 Spring提供的事务jar包

Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务

2.2 Jar包中的三个顶级接口

Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
  • PlatformTransactionManager:

    平台事务管理器,spring要管理事务,进行事务配置时,必须要使用事务管理器。

  • TransactionDefinition:

    事务详情(事务定义、事务属性),spring用于确定事务具体详情,

    例如:隔离级别、是否只读、超时时间等。

    进行事务配置时,必须要配置详情。spring将配置项封装到该对象实例。

  • TransactionStatus:

    事务状态,spring用于记录当前事务的运行状态。例如:是否有保存点,事务是否完成。

    spring底层根据状态进行相应操作。

2.3 PlatformTransactionManager 事务管理器

导入以下jar包

  • 不使用hibernate可以不导,只是了解一下
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务

之前常用的两个事务管理器

Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
以后操作数据库将使用mybatis的事务管理器

2.4 TransactionDefinition 事务定义

Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
  • 传播行为:在两个业务之间如何共享事务
PROPAGATION_REQUIRED required,必须 【默认值】【掌握】 支持当前事务,A如果有事务,B将使用该事务。 如果A没有事务,B将创建一个新的事务。
PROPAGATION_SUPPORTS supports ,支持 支持当前事务,A如果有事务,B将使用该事务。 如果A没有事务,B将以非事务执行。
PROPAGATION_MANDATORY mandatory ,强制 支持当前事务,A如果有事务,B将使用该事务。 如果A没有事务,B将抛异常。
PROPAGATION_REQUIRES_NEW requires_new ,必须新的【掌握】 如果A有事务,将A的事务挂起,B创建一个新的事务。 如果A没有事务,B创建一个新的事务。(不管A有没有事务,B都创建一个新事务)
PROPAGATION_NOT_SUPPORTED not_supported ,不支持 如果A有事务,将A的事务挂起,B将以非事务执行。 如果A没有事务,B将以非事务执行。(不管A有没有事务,B都以非事务执行)
PROPAGATION_NEVER never,从不 如果A有事务,B将抛异常。 如果A没有事务,B将以非事务执行
PROPAGATION_NESTED nested ,嵌套【掌握】 A和B底层采用保存点机制,形成嵌套事务。

2.5 TransactionStatus 事务状态

Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务

第三节 转账案例:使用Spring管理事务

3.1 环境搭建

第一步:创建数据库表

create database spring_day05;
use spring_day05;
create table account(
  id int primary key auto_increment,
  username varchar(50),
  money int
);
insert into account(username,money) values('jack','10000');
insert into account(username,money) values('rose','10000');

           
Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务

第二步:导入相关jar包

  • 核心:4+1(core、context、beans、expression)+logging(日志)
  • aop : 4 (aop联盟、spring aop、aspectj.weaver规范、spring aspect)
  • 数据库:2 (jdbc/tx事务)
  • 驱动:mysql
  • 连接池:c3p0
Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务

第三步:Dao层代码编写

  1. AccountDao接口代码
package com.it.dao;

/**
 * @author shuyy
 * @date 2020/9/15 
 */
public interface AccountDao {
    //支出
    void out(String outer,Integer money);

    //收入
    void in(String inner,Integer money);
}
           
  1. AccountDaoImpl实现类代码
package com.it.dao;

import org.springframework.jdbc.core.support.JdbcDaoSupport;

/**
 * @ClassName AccountDaoImpl
 * @Author shuyy
 * @Date 2020/9/15 
 **/
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{
    @Override
    public void out(String outer, Integer money) {
    	//支出
        getJdbcTemplate().update("update account set money = money - ? where username = ?",money,outer);
    }

    @Override
    public void in(String inner, Integer money) {
    	//收入
        getJdbcTemplate().update("update account set money = money + ? where username = ?",money,inner);
    }
}

           

第四步:Service层代码编写

  1. AccountService接口编写
package com.it.service;

public interface AccountService {
    
    //(支出,收入,金额)
    void transfer(String outer,String inner,Integer money);
    
}

           
  1. AccountServiceImpl实现类编写
package com.it.service;

import com.it.dao.AccountDao;

/**
 * @ClassName AccountServiceImpl
 * @Author shuyy
 * @Date 2020/9/15 
 **/
public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;//由spring注入,至少要提供set方法

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Override
    public void transfer(String outer, String inner, Integer money) {

        //支出
        accountDao.out(outer,money);

        //收入
        accountDao.in(inner, money);
    }
}

           

第五步:Spring的配置

  • 读取db.properties数据配置 -> 配置c3p0数据源 -> 配置dao -> 配置service
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context.xsd">


    <!--读取db.properties数据-->
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>

    <!--配置c3p0数据源
    注意:dbcp和c3p0的数据库连接的参数的属性名不一样,注意区别
    -->
    <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
        <property name="driverClass" value="${driverClass}"></property>
        <property name="jdbcUrl" value="${jdbcUrl}"></property>
        <property name="user" value="${user}"></property>
        <property name="password" value="${password}"></property>
    </bean>

    <!--配置dao-->
    <bean class="com.it.dao.AccountDaoImpl" id="accountDao">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--配置Service-->
    <bean class="com.it.service.AccountServiceImpl" id="accountService">
        <property name="accountDao" ref="accountDao"></property>
    </bean>
</beans>
           

第六步:测试与效果

@Test
    public void test1(){
        //转账测试
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //获取Service
        AccountService accountService = (AccountService) context.getBean("accountService");
        //jack转1000给rose
        accountService.transfer("jack","rose",1000);
    }
           
Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务

3.2 手动管理事务【了解】

  • spring底层使用 TransactionTemplate 事务模板进行操作
  • 操作步骤:
    1. service 需要获得 TransactionTemplate
    2. spring 配置模板,并注入给service
    3. 模板需要注入事务管理器
    4. 配置事务管理器:DataSourceTransactionManager ,需要注入DataSource
  • 了解底层即可,因为以后都是通过aop来配置事务

1. 修改Service

  • 配置spring事务模板TransactionTemplate
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
package com.it.service;

import com.it.dao.AccountDao;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

/**
 * @ClassName AccountServiceImpl
 * @Author shuyy
 * @Date 2020/9/15 
 **/
public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;//由spring注入,至少要提供set方法

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    //spring配置事务模板【提供set方法,由spring注入】
    private TransactionTemplate transactionTemplate;

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    @Override
    public void transfer(String outer, String inner, Integer money) {

        //通过事务模板执行业务
        this.transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {

                //支出
                accountDao.out(outer,money);

                int i = 1/0;//如果这里有错误就会回滚

                //收入
                accountDao.in(inner, money);
            }
        });
    }
}

           

2. 修改spring的配置文件

  • 逆推,要用事务模板就需要配置事务模板,配置事务模板还要配置事务管理器,配置事务管理器里面还要注入数据源dateSource
  • 手动管理事务比较麻烦【了解即可】
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context.xsd">


    <!--读取db.properties数据-->
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>

    <!--配置c3p0数据源
    注意:dbcp和c3p0的数据库连接的参数的属性名不一样,注意区别
    -->
    <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
        <property name="driverClass" value="${driverClass}"></property>
        <property name="jdbcUrl" value="${jdbcUrl}"></property>
        <property name="user" value="${user}"></property>
        <property name="password" value="${password}"></property>
    </bean>

    <!--配置dao-->
    <bean class="com.it.dao.AccountDaoImpl" id="accountDao">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--配置事务管理器-->
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="dataSourceTransactionManager">
        <!--配置dateSource-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--配置事务模板-->
    <bean class="org.springframework.transaction.support.TransactionTemplate" id="transactionTemplate">
        <!--事务管理器-->
        <property name="transactionManager" ref="dataSourceTransactionManager"></property>
    </bean>

    <!--配置Service-->
    <bean class="com.it.service.AccountServiceImpl" id="accountService">
        <property name="accountDao" ref="accountDao"></property>
        <!--事务模板-->
        <property name="transactionTemplate" ref="transactionTemplate"></property>
    </bean>
</beans>
           

3. 测试与效果

  • 有异常,数据会回滚,数据不变
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
  • 注释异常,再运行一次,测试手动配置事务后,能否运行成功
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务

3.3 工厂bean生成代理:半自动

  • Spring提供管理事务的代理工厂bean TransactionProxyFactoryBean

1. service无需配置事务模板

  • AccountServiceImpl实现类同最开始的环境配置
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务

2. 修改spring的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context.xsd">


    <!--读取db.properties数据-->
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>

    <!--配置c3p0数据源
    注意:dbcp和c3p0的数据库连接的参数的属性名不一样,注意区别
    -->
    <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
        <property name="driverClass" value="${driverClass}"></property>
        <property name="jdbcUrl" value="${jdbcUrl}"></property>
        <property name="user" value="${user}"></property>
        <property name="password" value="${password}"></property>
    </bean>

    <!--配置dao-->
    <bean class="com.it.dao.AccountDaoImpl" id="accountDao">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--配置事务管理器-->
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="dataSourceTransactionManager">
        <!--配置dateSource-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--配置Service-->
    <bean class="com.it.service.AccountServiceImpl2" id="accountService">
        <property name="accountDao" ref="accountDao"></property>
    </bean>

    <!--配置工厂代理-->
    <bean class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" id="transactionProxyFactoryBean">
        <!--接口-->
        <property name="proxyInterfaces" value="com.it.service.AccountService"></property>
        <!--目标对象-->
        <property name="target" ref="accountService"></property>
        <!--切面对象:spring做,无需写-->
        <!--事务管理器-->
        <property name="transactionManager" ref="dataSourceTransactionManager"></property>
        <!--transactionAttributes:配置事务的属性或详情(必须配置,不配置报错)
            key:写方法名
            value:写事务配置
            格式:PROPAGATION,ISOLATION,readOnly,-Exception,+Exception(后面3个可不配置,可选配置)
	               传播行为	  隔离级别  是否只读	 异常回滚	异常提交
        -->
        <property name="transactionAttributes">
            <props>
                <!--配置默认的传播行为和隔离级别-->
                <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop>
            </props>
        </property>
    </bean>
</beans>
           

3. 测试与效果

  1. 有异常,回滚,数据不变
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
  2. 注释异常,成功转账
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
  3. readOnly的使用(只读,不能修改),不设置异常也会报错,因为里面涉及修改数据,而readOnly是只读(数据不变)
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
  4. +Exception的使用(有异常也提交)
  • 先设置异常
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
  • 复制异常的类型,设置有异常也提交,再运行一下
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
  • 有异常,但是数据会提交(jack支付了,rose没收到)
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务

3.4 使用AOP配置事务【掌握】

  • 实现类同上

1. spring的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context.xsd
                            http://www.springframework.org/schema/aop
                            http://www.springframework.org/schema/aop/spring-aop.xsd
                            http://www.springframework.org/schema/tx
                            http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--读取db.properties数据-->
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>

    <!--配置c3p0数据源
    注意:dbcp和c3p0的数据库连接的参数的属性名不一样,注意区别
    -->
    <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
        <property name="driverClass" value="${driverClass}"></property>
        <property name="jdbcUrl" value="${jdbcUrl}"></property>
        <property name="user" value="${user}"></property>
        <property name="password" value="${password}"></property>
    </bean>

    <!--配置dao-->
    <bean class="com.it.dao.AccountDaoImpl" id="accountDao">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--配置事务管理器-->
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="txManager">
        <!--配置dateSource-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--配置Service-->
    <bean class="com.it.service.AccountServiceImpl2" id="accountService">
        <property name="accountDao" ref="accountDao"></property>
    </bean>

    <!--使用spring的aop标签来配置-->
    <!--1.配置通知事务管理器-->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <!--配置事务详情:传播行为、隔离级别-->
        <tx:attributes>
            <!--传播行为、隔离级别有默认,可以不配置,但是方法(tx:attributes)一定要配置,否则报错-->
            <tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT"/>
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <!--可以抽取为公共切入点,其它可以引用它-->
        <!--<aop:pointcut id="myPointCut" expression="execution(* com.it.service..*.*(..))"/>-->
        <!--2.事务与切入点关联--><!--这里的切入点表达式表示service包及其子包下的所有类和任意参数的方法都是切入点-->
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.it.service..*.*(..))"></aop:advisor>
    </aop:config>
</beans>
           
  • 注意要添加文件头
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务

2. 测试与结果

  1. 由于之前测试次数过多,将数据库数据重置一下
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
  2. 同样先测试有异常,数据库数据不变
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
  3. 注释异常,事务成功配置
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
  4. readOnly的设置(true只读)
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
  5. 有异常也提交(no-rollback-for)
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务

3.5 使用注解配置事务

  • 使用注解配置事务,注解可以写在一个类上也可以写在一个方法上
  • 每一个使用事务的类都要加上注解,不如在配置文件中来得一目了然

1.spring的配置

Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context.xsd
                            http://www.springframework.org/schema/aop
                            http://www.springframework.org/schema/aop/spring-aop.xsd
                            http://www.springframework.org/schema/tx
                            http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--读取db.properties数据-->
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>

    <!--配置c3p0数据源
    注意:dbcp和c3p0的数据库连接的参数的属性名不一样,注意区别
    -->
    <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource">
        <property name="driverClass" value="${driverClass}"></property>
        <property name="jdbcUrl" value="${jdbcUrl}"></property>
        <property name="user" value="${user}"></property>
        <property name="password" value="${password}"></property>
    </bean>

    <!--配置dao-->
    <bean class="com.it.dao.AccountDaoImpl" id="accountDao">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--配置Service-->
    <bean class="com.it.service.AccountServiceImpl2" id="accountService">
        <property name="accountDao" ref="accountDao"></property>
    </bean>

    <!--注解配置事务-->
    <!--1.配置事务管理器-->
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="txManager">
        <!--配置dateSource-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--2.开启事务注解驱动-->
    <tx:annotation-driven transaction-manager="txManager"></tx:annotation-driven>
</beans>
           

2. 测试与效果

  1. 先重置数据库数据,都为10000
  2. 使用注解配置事务(@Transactional)
  • @Transactional注解(readOnly与异常提交条件等都在其中)
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
  1. 默认可以不写传播行为与隔离级别,设置异常,回滚,数据不变
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
  2. 注释异常,成功配置
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务
    Spring管理事务介绍、Spring管理事务的环境搭建、Spring手动管理事务【了解】、Spring工厂代理半自动管理事务、SpringAOP管理事务【掌握】、Spring注解管理事务-day05第一节 事务的隔离级别【回顾】第二节 Spring事务管理介绍第三节 转账案例:使用Spring管理事务