五、事务操作2

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 五、事务操作2

2、在spring配置文件,开启事务注解

(1)在spring配置文件引入名称空间tx

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">

(2)开启事务注解

<!--开启事务注解-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

3、在service类上面(或者service类里面的方法上面)添加事务注解

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

(3)如果把这个注解添加到方法上面,为这个方法添加事务

@Service
@Transactional
public class UserService {
执行testAccount

数据没变

事务操作(声明式事务管理参数配置)

1、在service类上面添加注解@Transactional,在这个注解里面可以配置事务相关的参数


2、propagation:事务传播行为

(1)多事务方法之间进行调用,这个过程中事务是如何进行管理的




3、isolation:事务隔离级别

(1)事务有特性,称作隔离性,多事务操作之间不会影响。不考虑隔离性产生很多问题

(2)有三个读问题:脏读、不可重复读、虚(幻)读

(3)脏读:一个为提交事务读取到另一个为提交事务的数据


(4)不可重复读:一个未提交事务读取到另一提交事务修改数据


(5)虚读:一个未提交事务读取到另一提交事务添加数据

(6)通过设置事务隔离级别,解决读问题



4、timeout:超时时间

(1)事务需要在一定的时间内进行提交,如果不提交进行回滚

(2)默认值是-1,设置时间以秒单位进行计算

5、readOnly:是否只读

(1)读:查询操作,写:添加修改删除操作

(2)readOnly 默认值false,表示可以查询,可以添加修改删除操作

(3)设置readOnly 值是true,只能查询

6、rollbackFor:回滚

(1)设置出现哪些异常进行事务回滚

7、NoRrollbackFor:不回滚

(1)设置出现哪些异常不进行事务回滚

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

1、在spring配置文件中进行配置

第一步 配置事务管理器

第二步 配置通知

第三步 配置切入点和切面

src/新建bean2.xml
<?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="com.atguigu"></context:component-scan>
    <!-- 数据库连接池 -->
    <!-- 配置连接池 -->
    <!-- DruidDataSource dataSource = new DruidDataSource(); -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close"     >
        <property name="url" value="jdbc:mysql://localhost:3306/user_db?serverTimezone=UTC"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
        <property name="driverClassName" value="com.mysql.cj.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">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--2 配置通知    -->
    <tx:advice id="txadvice">
        <!-- 配置事务参数 -->
        <tx:attributes>
            <!-- 指定那种规则的方法上面添加事务 -->
            <tx:method name="accountMoney" propagation="REQUIRED"/>
<!--            <tx:method name="account*"/>-->
        </tx:attributes>
    </tx:advice>
    <!--3 配置切入点和切面-->
    <aop:config>
        <!-- 配置切入点       -->
        <aop:pointcut id="pt" expression="execution(* com.atguigu.spring5.service.UserService.*(..))"/>
        <!-- 配置切面       -->
        <aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
    </aop:config>
</beans>
UserService
package com.atguigu.spring5.service;
import com.atguigu.spring5.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
//@Transactional(readOnly = false,timeout = -1,propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)
public class UserService {
    //注入dao
    @Autowired
    private UserDao userDao;
    //转账的方法
    public void accountMoney(){
//        try {
            //第一步   开启事务
            //第二部   进行业务操作
            //lucy少100
            userDao.reduceMoney();
            //模拟异常
            int i=10/0;
            //mary多100
            userDao.addMoney();
            //第三步 没有发生异常,提交事务
//        } catch (Exception e) {
            //第四步 出现异常,事务回滚
//        }
    }
}
testTX
@Test
    public void testAccount1(){
        ApplicationContext context=new ClassPathXmlApplicationContext("bean2.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.accountMoney();
    }

事务操作(完全注解声明式事务管理)

1、创建配置类,使用配置类替代xml配置文件

spring5/新建config包/新建TxConfig
package com.atguigu.spring5.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
@Configuration  //配置类
@ComponentScan(basePackages = "com.atguigu")    //组件扫描
@EnableTransactionManagement    //开启事务
public class TxConfig {
    //创建数据库连接池
    @Bean
    public DruidDataSource getDruidDataSource(){
        DruidDataSource dataSource=new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/user_db?serverTimezone=UTC");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }
    //JdbcTemplate对象
    @Bean
    public JdbcTemplate getJdbcTemplate(DataSource dataSource){
        //到IOC容器中根据类型找到dataSource
        JdbcTemplate jdbcTemplate=new JdbcTemplate();
        //注入dataSource
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }
    //创建事务管理器
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){
        DataSourceTransactionManager transactionManager=new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}
UserService
package com.atguigu.spring5.service;
import com.atguigu.spring5.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional(readOnly = false,timeout = -1,propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)
public class UserService {
    //注入dao
    @Autowired
    private UserDao userDao;
    //转账的方法
    public void accountMoney(){
//        try {
            //第一步   开启事务
            //第二部   进行业务操作
            //lucy少100
            userDao.reduceMoney();
            //模拟异常
            int i=10/0;
            //mary多100
            userDao.addMoney();
            //第三步 没有发生异常,提交事务
//        } catch (Exception e) {
            //第四步 出现异常,事务回滚
//        }
    }
}
testTX
 @Test
    public void testAccount2(){
        ApplicationContext context=new AnnotationConfigApplicationContext(TxConfig.class);
        UserService userService = context.getBean("userService", UserService.class);
        userService.accountMoney();
    }
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
7月前
|
SQL Oracle 关系型数据库
第7章 事务
第7章 事务
41 0
|
9月前
|
存储 Java 中间件
事务一致性测试
事务一致性测试
71 0
|
9月前
|
SQL 前端开发 大数据
什么是大事务?以及大事务产生的问题
什么是大事务?以及大事务产生的问题
224 0
|
XML Java API
五、事务操作1
五、事务操作1
103 0
五、事务操作1
|
存储 Oracle 固态存储
深入理解事务
事务将应用程序的多个读、写操作捆绑在一起成为一个逻辑执行单元。即事务中的所有读写是一个执行的整体,整 个事务要么成功(提交)、要么失败(中止 或者 回滚)。如果失败,应用程序可以安全地重试。
16459 0
深入理解事务
|
人工智能 关系型数据库 MySQL
事务详解
事务是逻辑上的一组操作,要么都执行,要么都不执行。
84 0
|
SQL Java 大数据
事务详解(2)
你好看官,里面请!今天笔者讲的是事务。不懂或者觉得我写的有问题可以在评论区留言,我看到会及时回复。 注意:本文仅用于学习参考,不可用于商业用途,如需转载请跟我联系。
176 1
|
SQL 存储 关系型数据库
|
SQL Java 数据库
【事务与并发】- 不同事务读取相同数据问题
在加了事务的接口中,不同的业务或者是出现并发的时候,发现了一些SQL读取问题,两个都被事务包裹的方法,各自是隔离的,如果一方的事务延时提交,就会导致另一方读取出来的数据相同,并不是修改后的数据。
155 0
|
数据库
什么时候需要使用事务
什么时候需要使用事务
674 0