Spring5框架(五)——事务管理

事务的基本概念

  1. 事务是数据库操作的最基本单元,逻辑上一组操作,要么都成功,一旦有一个失败,则所有操作都失败
  2. 典型场景:银行转账
    (1)lucy转账100给Mary
    (2)Lucy少100,Mary多100
  3. 事务的四个特性(ACID)
    (1)原子性
    (2)一致性
    (3)隔离性
    (4)持久性

搭建事务操作环境(模拟转账操作)

图解说明结构逻辑

  1. JavaEE操作的三层结构:Web层(视图层)、Service层(业务逻辑层)、Dao层(数据(库)操作层)
    在这里插入图片描述
  2. 初始化数据库的表信息
    在这里插入图片描述
    在这里插入图片描述

导入依赖包

同Spring框架(四)JdbcTemplate的依赖包

xml配置文件,同Spring框架(四)JdbcTemplate

<?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: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">
    <!--开启注解扫描-->
    <context:component-scan base-package="com.spring.transaction"></context:component-scan>

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="jdbc:mysql:///user_db?characterEncoding=UTF-8" />
        <property name="username" value="root" />
        <property name="password" value="230519" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    </bean>

    <!--JdbcTemplate对象的创建-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--注入dataSource-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

</beans>

实现Service层和Dao层的功能

  1. Dao层
public interface UserDao {
    public void addMoney();
    public void reduceMoney();
}

@Repository
public class UserDaoImpl implements UserDao{
    //注入JdbcTemplate
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void addMoney() {
        String sql = "update t_account set money=money+? where username=?";
        jdbcTemplate.update(sql,100,"mary");
    }

    @Override
    public void reduceMoney() {
        String sql = "update t_account set money=money-? where username=?";
        jdbcTemplate.update(sql,100,"lucy");

    }

}

  1. Service层
@Service
public class UserService {
    //注入Dao
    @Autowired
    private UserDao userDao;
    public void accountMoney(){
        userDao.reduceMoney();
        userDao.addMoney();
    }
}
  1. 测试方法
    @Test
    public void testAccount(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.accountMoney();
    }
  1. 测试结果
    在这里插入图片描述

事务场景引入(模拟事务的特性)

问题引入

在转账过程中出现异常
在这里插入图片描述
结果:
在这里插入图片描述
分析:lucy的账户少了100,但由于出现了异常,导致mary的账户没有增加100,由此引入事务的特性

事务的解决方式

  1. 解决逻辑
    在这里插入图片描述
  2. 具体实现事务管理
    ** 一般将事务添加导Java EE三层结果的Service层(业务逻辑层)**
    (1)编程式事务管理(1中的解决逻辑的代码实现)
    (2)声明式事务管理(主要使用该方式)

声明式事务管理

** 在Spring进行声明式事务管理时,底层使用导了AOP原理**

  1. 实现方式
    (1)基于注解方式(主要使用)
    (2)基于xml配置文件方式(略)
  2. Spring提供了一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类
    在这里插入图片描述
基于注解方式实现过程
  1. xml配置文件(在原先的xml配置文件内容基础上添加)
    (1)引入tx名称空间
    (2)创建事务管理器,注入数据库信息
    (3)开启事务注解,注入事务管理器
<?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:context="http://www.springframework.org/schema/context"
       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/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--开启注解扫描-->
    <context:component-scan base-package="com.spring.transaction"></context:component-scan>

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="jdbc:mysql:///user_db?characterEncoding=UTF-8" />
        <property name="username" value="root" />
        <property name="password" value="230519" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    </bean>

    <!--JdbcTemplate对象的创建-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--注入dataSource-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--1.创建事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入dataSource-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--开启事务注解-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

</beans>
  1. 在Service层的类上面(或类中的方法上面)添加事务注解@Transactional
    (1)如果注解在类上面,表示对该类中的所有方法都添加事务
    (2)如果注解在方法上面个,表示只对该方法添加事务
@Service
@Transactional
public class UserService {
    //注入Dao
    @Autowired
    private UserDao userDao;
    public void accountMoney(){
        userDao.reduceMoney();
        int i = 10/0;
        userDao.addMoney();
    }
}

  1. 测试结果
    在这里插入图片描述
    转账过程出现异常,两个账户都没有改动
@transactional注释的参数配置

在这里插入图片描述

  • propagation:事务传播行为
    (1)多事务方法直接进行调用,这个过程中事务是如何管理的
    (1)事务方法:对数据库中数据进行改变的操作
    (2)在一个方法中调用另一个方法,且其中一个方法没有事务管理注解
    在这里插入图片描述
    (3)7种事务传播行为
    在这里插入图片描述
    主要使用前两种:
    在这里插入图片描述
  • ioslation:事务隔离级别
    (1)事务有特性称为隔离性,多事务操作之间不会产生影响。如果不考虑隔离性会产生很多问题。
    (2)三个读的问题:脏读、不可重复读、虚(幻)读
    【1】脏读(致命问题):一个未提交事务读到另一个未提交事务的修改数据。一个用户A更改了数据库中的数据,但还未提交,另一个用户B此时读取到的是更改后的数据,但如果用户A进行事务回滚,则用户B实际拿到的数据并不是真正的数据。
    在这里插入图片描述
    【2】不可重复读(现象):一个未提交的事务读到另一个已提交事务修改的数据
    在这里插入图片描述
    【虚读】:未提交事务读到另一个提交事务的添加数据
    (3)通过隔离级别的设置解决三个读问题
    在这里插入图片描述
  • timeout:超时时间
    (1)事务需要在一定时间内进行提交,如果不提交进行回滚
    (2)默认值是-1,表示不回滚。如果设置时,单位时秒
  • readOnly:是否只读
    (1)读:查询操作;写:添加修改删除操作
    (2)readOnly默认值为false,表示可以查询,也可以添加删除修改
  • rollbackFor:回滚
    (1)设置出现哪些异常进行事务的回滚
  • noRollbackFor:不回滚
    (1)设置出现哪些异常不进行事务的回滚
完全注解开发

使用配置类代替xml配置文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值