Spring5总述(八)—— 事务管理操作

了解更多关于Spring的基础知识

1、事务操作概念与特性

(1)事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败,那么所有操作都会失败

(2)事务操作的典型场景:银行转账
在这里插入图片描述
(3)事务操作四个特性

  • 原子性
  • 一致性
  • 隔离性
  • 持久性

2、事务管理操作介绍

  1. 事务管理操作添加到JavaEE三层结构里面的service层上(业务逻辑层)
  2. 在Spring中进行事务管理操作,两种方式:编程式事务管理、声明式事务管理,目前的事务操作主要使用声明式事务管理进行实现
  3. 声明式事务管理操作
    • 基于注解方式实现(大多数使用情况)
    • 基于xml配置文件方式
  4. 在Spring中进行声明式事务管理操作,底层使用AOP原理实现
  5. 在Spring中进行事务管理,这里需要使用到的一个接口:DataSourceTransactionManger,代表事务管理器

3、利用事务操作解决上述银行转账问题(注解方式实现)

  1. 在Spring配置文件中配置数据库连接池,并配置JdbcTemplate对象
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="url" value="jdbc:mysql:///bank"></property>
        <property name="username" value="root"></property>
        <property name="password" value="lll159357."></property>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    </bean>

    <!--JdbcTempla对象-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--注入dataSource-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>
  1. 在Spring配置文件中配置事务管理器,注入数据源
    <!--创建事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源-->
        <proper name="dataSource" ref="dataSource"></property>
    </bean>
  1. 开启事务注解和组件扫描(1.引入名称空间tx和context;2.开启事务注解和组件扫描)
	   xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="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="bank_service,bank_dao"></context:component-scan>
    <!--开启事务注解-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
  1. 创建以下包和类

在这里插入图片描述
UserDao:

public interface UserDao {
    public void add();
    public void reduce();
}

UserDaoImpl:实现UserDao

@Component
public class UserDaoImpl implements UserDao{

    @Autowired
    private JdbcTemplate jdbcTemplate;

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

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

UserService:实现业务操作

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    public void accountMoney(){
            userDao.reduce();
            int i = 10/0;
            userDao.add();
    }
}

  1. 创建测试类运行测试(没有在业务层添加事务操作
public class test_bank {
    @Test
    public void text(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.accountMoney();
    }
}

运行前数据库表展示:
在这里插入图片描述
报错展示:
在这里插入图片描述
运行后数据库表展示:
在这里插入图片描述

  1. 创建测试类运行测试(在业务层添加了事务操作

(1)@Transactional,这个注解可以添加到类上面,也可以添加到方法上面
(2)如果把这个注解添加到类上面,这个类里面所有的方法都添加事务
(3)如果把这个注解添加方法上面,为这个方法添加事务

@Service
@Transactional
public class UserService {

    @Autowired
    private UserDao userDao;

    public void accountMoney(){
            userDao.reduce();
            int i = 10/0;
            userDao.add();
    }
}

运行前数据库表展示:
在这里插入图片描述
报错展示:
在这里插入图片描述
运行后数据库表展示:这段代码前面会执行减少钱的方法,但是因为开启了事务操作,即使中途出现了除零异常,也能够避免出现只减不加的情况出现,因为事务操作会让程序中断之前改变的数据进行回滚复原:
在这里插入图片描述

4、注解@Transactional中的相关参数

在这里插入图片描述
下面就对以上画红线的六种参数进行介绍
(1)propagation:事务传播行为,通过一个有事务方法调用一个无事务方法,或者反过来

属性值:Propagation.下面表格中的属性值 在这里插入图片描述

(2)isolation:事务隔离级别

  1. 多事务操作之间不会产生影响,不考虑隔离性会产生很多问题
  2. 有三个读问题:脏读,不可重复读,虚(幻)读
  • 脏读:一个未提交事务读取另一个未提交事务的数据
  • 不可重复读:一个未提交事务读取到另一提交事务修改数据
  • 虚读:一个未提交事务读取到另一提交事务添加数据
  1. 通过设置事务隔离性,解决读问题

属性值:Isolation.下面表格属性 在这里插入图片描述

(3)timeout:超过时间

  1. 事务需要在一定时间内提交,如果不提交则进行回滚
  2. 默认值为-1,设置时间以秒为单位进行计算

(4)readOnly:是否只读

  1. 读:查询操作;写:添加修改删除操作
  2. readOnly默认值为false,表示可以查询,可以添加修改删除
  3. 设置readOnly值为true,则只能查询

(5)rollbackFor:回滚

  1. 设置出现那些异常进行事务的回滚

(6)noRollbackFor:不回滚

  1. 设置出现那些异常不进行事务的回滚

5、事务操作(XML声明式事务管理)

  1. 在Spring配置文件中进行相应配置,并且将UserService类中的@Transactional删去
<?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: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">

    <context:component-scan base-package="bank_service,bank_dao"></context:component-scan>

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="url" value="jdbc:mysql:///bank"></property>
        <property name="username" value="root"></property>
        <property name="password" value="lll159357."></property>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    </bean>

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

    <!--创建事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--配置通知 -->
    <tx:advice id="txadvice" >
        <!--配置事务参数-->
        <tx:attributes>
            <tx:method name="accountMoney" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <!--配置切入点和切面-->
    <aop:config>
        <aop:pointcut id="pt" expression="execution(* bank_service.UserService.*(..))"/>
        <aop:advisor advice-ref="txadvice" pointcut-ref="pt"></aop:advisor>
    </aop:config>
</beans>

6、事务操作(完全注解开发实现声明式事务管理)

  1. 创建配置类,使用配置类替代xml配置文件
@Configuration
@ComponentScan(basePackages = "bank_service")
@ComponentScan(basePackages = "bank_dao")
@EnableTransactionManagement
public class TxConfig {
    //创建数据库连接池
    @Bean
    public DruidDataSource getDruidDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource.setUrl("jdbc:mysql:///bank");
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("lll159357.");
        return druidDataSource;
    }

    //创建JdbcTemplate对象
    @Bean
    public JdbcTemplate getJdbcTemplate(DataSource dataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }

    //创建事务管理器对象
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource);
        return dataSourceTransactionManager;
    }
}
  1. 数据库操作类和Service类均不变
  2. 创建测试类
public class test_bank {
    @Test
    public void text1(){
        ApplicationContext context = new AnnotationConfigApplicationContext(TxConfig.class);
        UserService userService = context.getBean("userService", UserService.class);
        userService.accountMoney();
    }
}

❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤
若对Spring基础知识感兴趣的可以关注一下博主,我会持续更新Spring基础知识(一边学习一边记录),一起进步,有错误的地方也可以在评论区指出来喔,谢谢大家啦!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

offer冲冲冲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值