深入理解 MySQL —— MySQL 事务

1. 什么是事务?

事务是数据操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作。

事务是一组不可在分割的操作集合(工作逻辑单元)。

1.1 典型事务场景

以转账为例:

update user_account set balance = balance - 1000 where user_id = 3;

1.2 如何开启事务

  1. mysql 中开启事务

    begin/start transaction;
    commint/rollback;
    
    set session autocommit = on/off;
    
  2. jdbc 编程开启事务

    connection.setAutoCommit(false)
    

2. 事务 ACID 特性

  • 原子性(Atomicity)

    原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

  • 一致性(Consistency)

    事务前后数据的完整性必须保持一致。

  • 隔离性(Isolation)

    事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

  • 持久性(Durability)

    持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,即使数据库发生故障也不应该对其有任何影响。

2.1 原子性(Atomicity)

针对同一个事务

在这里插入图片描述

这个果汁包含两个步骤:

  1. A:800 -200 = 600
  2. B:200 + 200 = 400

原子性表示这两个步骤一起成功,或者一起失败,不能只发生其中一个动作。

2.2 一致性(Consistency)

针对一个事务操作前后的状态一致

在这里插入图片描述

  1. 操作前

    A:800,B:200
    
  2. 操作后

     A:600,B:400
    

一致性表示事务完成后,符合逻辑运算。

2.3 隔离性(Isolation)

针对多个用户同时操作,主要是排除其他事务对本次事务的影响。

在这里插入图片描述

两个事务同时进行,其中一个事务读取到另外一个事务还没有提交的数据,B

在这里插入图片描述

2.4 持久性(Durability)

表示事务结束后的数据不随着外界原因导致数据丢失。

操作前

A:800,B:200

操作后

A:600,B:400

如果在操作前(事务还没有提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该为

A:800,B:200

如果在操作后(事务已经提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该为

A:600,B:400

3. 事务并发带来的问题

3.1 脏读

指一个事务读取了另外一个事务未提交的数据。

在这里插入图片描述

事务 A 读取了事务 B 未提交的事务,输出结果为:18。

3.2 不可重复读

在一个事务内读取表中的某一行数据,多次读取结果不同。

在这里插入图片描述

在事务 B 的执行过程中,事务 A 多次读取结果不一样。

3.3 幻读

是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。

在这里插入图片描述

4. 事务隔离级别设置

4.1 数据库设置事务隔离级别

设置事务隔离级别

--读 未提交
set TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
--读 已提交
set TRANSACTION ISOLATION LEVEL READ COMMITTED;
--可重复读
set TRANSACTION ISOLATION LEVEL REPEATABLE READ;
--序列化(串行化)
set TRANSACTION ISOLATION LEVEL SERIALIZABLE;

查询当前事务隔离级别

select @@tx_isolation 
表 四种隔离级别
| 设置 | 描述 | | ---------------- | -------------------------------------------------- | | Serializable | 可避免脏读、不可重复读、虚读情况的发生。(串行化) | | Repeatable read | 可避免脏读、不可重复读情况的发生。(可重复读) | | Read committed | 可避免脏读情况发生(读已提交)。 | | Read uncommitted | 最低级别,以上情况均无法保证。(读未提交) |

4.2 java 代码设置事务隔离级别

适当的 Connection 方法,比如 setAutoCommitsetTransactionIsolation

设置描述
TRANSACTION_SERIALIZABLE指示不可以发生脏读、不可重复读和虚读的常量。
TRANSACTION_REPEATABLE_READ指示不可以发生脏读和不可重复读的常量;虚读可以发生。
TRANSACTION_READ_UNCOMMITTED指示可以发生脏读 (dirty read)、不可重复读和虚读 (phantom read) 的常量。
TRANSACTION_READ_COMMITTED指示不可以发生脏读的常量;不可重复读和虚读可以发生。

5. Innodb 引擎对事务隔离级别的支持

在这里插入图片描述

隔离级别到底是如何实现的呢?下一节我们通过分析 mysql 的锁和 MVCC 机制来讲解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值