IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring学习之事务操作 -> 正文阅读

[Java知识库]Spring学习之事务操作

目录

事务的概念

事务引入

Spring事务管理

介绍

基于注解方式实现声明式事务管理

声明式事务管理参数配置

基于XML方式实现声明式事务管理

基于完全注解方式实现声明式事务管理


事务的概念

什么是事务

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

②:典型场景:银行转账。

事务的四大特性(ACID)

①:原子性

②:一致性

③:隔离性

④:持久性

事务引入

我们使用常见的银行转账案例来引入事务的操作。

思路:将数据库中一个人的账户金额减去转账金额,另一个人的加上转账金额。

步骤

①:创建数据库,创建对应表,添加相应的记录

CREATE TABLE t_account(
id VARCHAR(20),
username VARCHAR(50),
money INT
)

????????????????????????????????????????

②:创建 service ,搭建 dao,完成对象创建和对象注入关系。

service --->?dao,?dao ---> JdbcTemplate,JdbcTemplate ---> DataSource

③:在 dao 中创建两个方法:多钱与少钱,在 service 中创建转账的方法

????????UserDao接口

public interface UserDao {
    //少钱
    public void reduceMoney();
    //多钱
    public void addMoney();
}

????????UserDaoImp

@Repository
public class UserDaoImp implements UserDao{
    @Autowired
    private JdbcTemplate jdbcTemplate;

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

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

????????UserService

@Service
public class UserService {
    @Autowired
    private UserDao userDao;
    //转账方法
    public void moveMoney(){
        userDao.reduceMoney();
        userDao.addMoney();
    }
}

④:测试

public class UserTest {
    @Test
    public void test1(){
        ApplicationContext context = new FileSystemXmlApplicationContext("G:\\SpringStudy\\Spring-TranOperation\\bean1.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.moveMoney();
    }
}

?????????????????????????????????????????????????????????????

注意点:

如果上面代码正常执行,那么不会出现问题;但是如果在执行过程中出现了异常,那么可能就会导致一些问题。

根据上面案例我们来模拟银行转账过程中断电的情况

??????????????????????表初始状态 ???????

????????????????????????????????????????

????????手动添加异常:在张三执行少钱操作后,添加一个除 0 操作,其余不变

//转账方法
    public void moveMoney(){
        userDao.reduceMoney();
        //使用除 0 操作来模拟转账过程中断电
        int num = 1 / 0;
        userDao.addMoney();
    }

????????????????执行后表结果:

我们可以发现张三账户的钱已经转出了,但李四的账户却没有收到,导致总钱数发生了变化。这种情况我们就可以使用事务来进行解决。

???????????????????????????????????????????????????????????????????????????

Spring事务管理

介绍

1、事务一般是添加到 JavaEE 三层结构里面的 Service 层(业务逻辑层)

2、在 Spring 进行事务管理操作,有两种方式

??? ??? ?编程式事务管理和声明式事务管理(常用)

3、声明式事务管理(底层使用了 AOP 原理)

??? ??? ?① 基于注解方式(常用)

??? ??? ?② 基于 XML 配置方式

4、Spring 事务管理常用 API (提供了一个事务管理器接口 PlatformTransactionManager ,针对? 不同的框架提供不同的实现类)

基于注解方式实现声明式事务管理

1、在 spring 配置文件中配置事务管理

??????JdbcTemplate 使用的是DataSourceTransactionManager 实现类

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

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

????????①:在 spring 配置文件中引入名称空间 tx ,和之前配置名称空间方法一样

????????②:开启事务注解

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

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

????????①:@Transactional,该注解可以添加在类上面,也可以添加到方法上面

????????②:如果把这个注解添加到类上面,表明这个类里面的所有方法都被添加了事务

???????????????如果添加到方法上面,表明该方法被添加了事务

4、基于上面的小例子进行测试

????????修改后的 UserService 类 ???????

@Service
public class UserService {
    @Autowired
    private UserDao userDao;
    //转账方法
    @Transactional
    public void moveMoney(){
        userDao.reduceMoney();
        //使用除 0 操作来模拟转账过程中断电
        int num = 1 / 0;
        userDao.addMoney();
    }
}

????????异常 ???????

???????

????????结果:可以发现当出现异常后,执行了回滚操作,恢复已经被修改的数据

?

声明式事务管理参数配置

?在 @Transactional 注解里面配置事务相关参数,主要参数如下

????????①:propagation:事务传播行为

????????????????事务传播行为:多事务方法直接进行调用,这个过程中事务是如何进行管理的

????????????????事务方法:使数据库表数据进行变化的操作

????????????????事务的传播行为可以有由传播属性指定。Spring指定了 7 种传播行为

?常用的是 REQUIRED(默认)REQUIRES_NEW, 配置如下

????????②:isolation:事务隔离级别

????????????????<1> 事务有隔离性的特性,多事务操作之间不会产生影响

????????????????<2> 如果不考虑隔离性会产生脏读不可重复读虚(幻)读 等问题。

????????????????????????脏读:一个未提交的事务读取到另一个未提交事务的数据,若后者执行了回滚操作,就导致前者读到了脏数据

????????????????????????不可重复读:一个未提交事务读取到了一个已提交事务修改后的数据,导致几次读取到的数据不一致

????????????????????????虚读:一个未提交事务读取到另一提交事务修改数据的记录,导致几次读取到的数据记录不一致

通俗理解可查看该博客【数据库】快速理解脏读、不可重复读、幻读阳阳的博客-CSDN博客脏读

????????????????<3> 解决:通过设置事务隔离性,解决读问题,MySql 中默认是可重复读级别

????????③:timeout:超时时间

????????????????事务需要在一定时间内提交,如果不提交就会进行事务回滚

????????????????默认是 -1,也就是不回滚;但可以自己设置,单位是秒

????????④:readOnly:是否只读

????????????????读:查询操作;写:增、删、改

????????????????默认值是 false,可以执行增、删、改、查操作

????????????????可以设置为 true,只可以执行查操作

????????⑤:rollbackFor:回滚

????????????????设置查询哪些异常进行事务回滚

????????⑥:noRollbackFor:不回滚

????????????????设置出现哪些异常不进行回滚

基于XML方式实现声明式事务管理

在 spring 配置文件中进行配置

????????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="moveMoney" propagation="REQUIRES_NEW"/>
                <!--以 move 为开头的方法-->
            <tx:method name="move*"/>
        </tx:attributes>
    </tx:advice>

????????3、配置切入点和切面

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

基于完全注解方式实现声明式事务管理

????????创建配置类,使用配置类来替代 xml 配置文件

@Configuration  //配置类
@ComponentScan(basePackages = "com.zhouyue")
@EnableTransactionManagement //开启事务
public class TxConfig {
    //创建数据库连接池
    @Bean
    public DruidDataSource getDruidDataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/user_db");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }

    //创建 JdbcTemplate 对象
    @Bean
    public JdbcTemplate getJdbcTemplate(DataSource dataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        //到 IOC 容器中根据类型找到 dataSource
        //注入dataSource
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }

    //创建事务管理器
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource);
        return dataSourceTransactionManager;
    }
}

????????测试方法

    @Test
    public void test2(){
        ApplicationContext context = new AnnotationConfigApplicationContext(TxConfig.class);
        UserService userService = context.getBean("userService", UserService.class);
        userService.moveMoney();
    }

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-01-03 15:56:35  更:2022-01-03 15:57:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:27:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码