高性能Mysql:事务特性及实战

一、开篇简介

事务的作用我就不再提及了, 相信看到这篇文章的基本上都会知道事务的概念。本篇文章首先会介绍一下事务的特性、四种隔离级别以及对应的实战测试,希望帮读者加深事务的理解。

二、事务的ACID特性

  • 原子性(atomicity)

    一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部成功,要么全部失败

  • 一致性(consistency)

    数据库永远是从一个一致性状态转向另一个一致性状态,举个例子就是银行进行转账,倘若事务失败,无论如何都要保证银行中所有的钱的数量不会变化,也就是说数据不会被事务破坏。

  • 隔离性(isolation)

    一般来说,事务所做的修改会在最终提交之前,对其他事务不可见。后面的隔离级别也是针对隔离性这个特性。

  • 持久性(durability)

    一般来说,一旦事务提交,数据就会被永久保存到数据库中。

三、事务隔离级别

  • RU(read uncommited)

    顾名思义,可以读没有提交的数据,这种行为也成为脏读,真正的开发中会很少使用。

  • RC(read commited)

    读已提交的事务,一个事务在开始的时候只能看见已经提交的事务,也就是说一个事物在提交之前,对其他事务不可见。但是这种是无法防止在一个事务中重复读的,比如A事务第一次查询数据B=200,接着B事务修改B=300并提交,这样A事务第二次查询B=300,这种就是不可重复读。

  • RR(repeatable read)

    可重复读,保证了同一个事务多次读取同样的结果是一致的。但是这种隔离级别仍然无法解决幻读的问题。幻读:当某个事务A在读取某个范围内的记录时,另一个事务B又在该范围内插入了新的记录,当A再次查询这个范围的记录,会出现幻行的情况。

  • Serializable(串行化)

    这种是强行给每个事务加锁,达到事务完全串行的结果,并发性极差,一般不考虑

隔离级别脏读可能不可重复读幻读
RUYESYESYES
RCNOYESYES
RRNONOYES
SerializeNONONO

TIPS :在任何隔离级别下,对数据的写都是会加锁的

四、隔离级别实战

先创建一个表 transaction_test作为测试使用:

CREATE TABLE `transaction_test` (
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  • RU(未提交读)

这里开启两个窗口作为两个session会话,并设置会RU级别:

然后用session A 插入一条数据

 insert into transaction_test (id,name) values (1,'A');

在 session B中可以马上查看到插入的数据。

再演示一下写时锁行的情况

可以看到这时session B正处于锁定状态,因为session A还没有提交。

  • RC(读已提交)

首先让sesseion A 插入一条记录。

 insert into transaction_test (id,name) values (2,'A');

由于没有提交,所以B不会看到这条记录,一旦A提交后,由于隔离级别不能防止不可重复读,所以当A提交后,B再次查询会多出一条记录。

  • RR(不可重复读)

不可重复读是mysql默认隔离级别,可以重复一下上一次的实验。A插入一条记录,就算A提交后,B查询的记录依然不会变。

TIPS:大家要是做实验的时候需要将 autocommit 设置为0,防止自动提交

第四种隔离方式这里就不再做实验测试了


感谢您的阅读

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值