MySql事务特性、隔离级别

事务

现在的软件都是大并发的操作数据,然而为了保证操作数据的正确性。就提出了事务。

事务的特性

事务必须满足的4个条件(ACID):原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。

  1. 原子性:一个事务(Transaction)中的所有操作要么都执行成功,要么都失败。事务在执行过程中,如果发生错误则会回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过。数据不会有任何改变。
  2. 一致性:在事务开始前和结束后,数据的完整性没有被破坏。
  3. 隔离性:数据库允许多个事务并发对其数据进行读取和修改,隔离性是防止多个事务交叉执行时读取数据不一致问题。事务的隔离级别分为,未提交读(Read uncommitted)、提交读(Read committed)、可重复读(Repeatable read)和串行化(Serializable)。
  4. 持久性:事务提交后,对数据的修改是永久性的,提交的数据不会丢失。

事务的隔离级别

  1. 未提交读(Read uncommitted):可以读取其它所有事务未提交事务的执行结果。读取未提交的数据,称之为脏读(Dirty Read)。
  2. 提交读(Read committed):一个事务只能读取其它事务已提交的数据。
  3. 可重复读(Repeatable read):保证同一事务的多个实例在并发读取数据时,会看到同样的数据行。MySQL默认隔离级别。
  4. 串行化(Serializable):每个事务排队执行,最高的隔离级别,避免了脏读不可重复读幻读
举例
  1. 用到的MySQL命令
命令作用
select version();查看数据库版本
select @@tx_isolation;# 8以前版本
select @@transaction_isolation;# 8以后版本
查看当前事务隔离级别
set session transaction isolation level 隔离级别当前会话的隔离级别
start transaction开启事务
commit提交事务
rollback回滚事务
  1. 建表
CREATE TABLE `tb_account` (
  `id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(10) DEFAULT NULL COMMENT '姓名',
  `balance` decimal(10,4) DEFAULT NULL COMMENT '余额',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
  1. 脏读
顺序会话1会话2
1# 设置隔离级别为 未提交读
set session transaction isolation level read uncommitted;
2# 开启事务
start TRANSACTION;
# 开启事务
start TRANSACTION;
3在这里插入图片描述
4在这里插入图片描述
5在这里插入图片描述
6在这里插入图片描述
7在这里插入图片描述

在会话1中,顺序7查询结果为会话2中未提交事务修改的数据,即是 脏读

  1. 不可重复读
顺序会话1会话2
1# 设置隔离级别为 提交读
set session transaction isolation level read committed;
2# 开启事务
start TRANSACTION;
# 开启事务
start TRANSACTION;
3在这里插入图片描述
4在这里插入图片描述
5在这里插入图片描述

在会话1中,顺序3和5读取到的数据不同,是因为其间会话2对数据进行了修改,并提交。如果不提交,查询余额依然是0,避免了脏读。一个事务中两次的查询结果不一致,即为不可重复读。

  1. 可重复读
顺序会话1会话2
1# 设置隔离级别为 可重复读
set session transaction isolation level REPEATABLE read;
2# 开启事务
start TRANSACTION;
# 开启事务
start TRANSACTION;
3在这里插入图片描述
4在这里插入图片描述
5在这里插入图片描述

与不可重复读的区别在于,无论会话2的事务是否已经提交,都不会改变会话1的查询结果。

  1. 幻读

所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行。InnoDB存储引擎通过多版本并发控制(MVCC)解决了幻读的问题。

顺序会话1会话2
1# 设置隔离级别为 可重复读
set session transaction isolation level REPEATABLE read;
2# 开启事务
start TRANSACTION;
# 开启事务
start TRANSACTION;
3在这里插入图片描述
4INSERT INTO tb_account VALUE (3, ‘王五’, 1000);
COMMIT;
在这里插入图片描述
5在这里插入图片描述

在会话1中顺序3查询id为3的记录为空,此时,会话2插入id为3的数据,并提交。会话1再去插入id为3的数据时就会报主键冲突异常。即为幻读。
防止读到修改或删除数据需要加行级锁。
防止读到新增数据一般就需要加表级锁。

不可重复读和幻读的区别在于,不可重复读会读到修改或者删除的数据,幻读是会读到其它事务已提交的数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值