Welcome everyone

事务和隔离级别知识整理

mysql 汪明鑫 748浏览 3评论

大学学过,自己也看过,奈何总是遗忘,特别是隔离级别相关概念,

感觉这一块的知识掌握水平还处在背面试题阶段。。。

最近看过一篇文章,感觉这一块水还是很深的,有必要重新拾起,先简单整理下,后续再加深学习

 

事务定义

一个最小的不可再分的工作单元  Transaction

为了避免操作数据库出现数据不一致问题

 

ACID

面试必问

 

  • A: Atomicity 原子性
  • C: Consistency 一致性
  • I: Isolation 隔离性
  • D: Durability  持久性

 

原子性:事务是一个不可分割的原子性操作,要么都执行,要么都不执行,不会只执行一般

一致性:事务中数据不可能凭空产生或者消失,前后保持一致;比如转账过程中,转账前后,双发金额总和不变

隔离性:事务与事务之间是隔离,防止事务间操作互相影响;隔离性又分为不同的隔离级别,见下文

持久性:事务执行完数据的修改是永久的(存入硬盘)

 

还记得最开始学习JDBC,我们要手动开启事务和提交事务,如果异常会自动rollback

 

mysql事务使用方式

1,用 BEGIN, ROLLBACK, COMMIT来实现

  • BEGIN 开始一个事务
  • ROLLBACK 事务回滚
  • COMMIT 事务确认

2,直接用 SET 来改变 MySQL 的自动提交模式:

  • SET AUTOCOMMIT=0 禁止自动提交
  • SET AUTOCOMMIT=1 开启自动提交

 

隔离级别

根据上文ACID的定义,事务之间是有一定的隔离性

隔离性是等级的概念,等级高低事务之间的影响性不同

 

  • 读未提交(Read uncommitted)
  • 读提交(read committed)
  • 可重复读(repeatable read)
  • 串行化(Serializable)

 

读未提交是级别最低的隔离级别,串行化是最高隔离级别,不允许事务并行执行,完全串行,

不会造成任何数据不一致问题,也不是我们讨论的重点

隔离级别越高,虽然数据更安全,但是数据库的并发性就越差

因此既不会设置最低的隔离级别也不会设置最高的隔离级别

 

事务并发造成的数据不一致问题

  • 脏读

读未提交的隔离级别下会造成脏读,顾名思义,读取到脏数据,什么是脏数据,就是读到另一个事务没有提交的数据

举个不恰当的例子,如果银行转账事务设置成读未提交,你欠了别人1万块钱,你开启事务,然后给别人转1万钱,然后打电话说你已经还他钱了,

然后他就去看自己的余额确实多了1万,然后你这边不提交事务,来波回滚…不就舒服了嘛

但是现实不可能这样的,你想到的漏洞,程序员早都想到了…

脏读就是读取了另一个事务未提交的事务,生产上不会用读未提交隔离级别

 

  • 不可重复读

一个事务多次读取的数据出现不一致,由于另一个事务在并发的执行更新数据操作并提交事务

读提交下会出现这种情况

 

  • 幻读

就像是幻觉一样,再次读取数据凭空多了一行数据或少了一行数据(说明屏蔽不了insert和update的影响)

 

 

个人认为不可重复读和幻读比较容易混淆,不可重复读是对某一行数据而言是否变化,而幻读是对于查询出来的所有数据是不是多了或者少了某一条

 

 

趁热打铁,贴上我从网上盗的一个对应表

 

大家可能发现了这和我们大学学的还是有点不一样的

就是可重复读的隔离级别,不会发生幻读(innodb)

 

mysql隔离级别

查看默认隔离界别:
select @@tx_isolation;


设置隔离级别:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

 

实验验证理论

开2个窗口,便于测试mysql事务的并发执行

 

创建一个表,并插入2条数据

create table  person ( name varchar(20), age int );

insert into person(name,age) values("doinb",24),("xiaotian",20);
mysql> select * from person
    -> ;
+----------+------+
| name     | age  |
+----------+------+
| doinb    |   24 |
| xiaotian |   20 |
+----------+------+
2 rows in set (0.00 sec)

 

下面我们把各场景都模拟一下

 

读未提交:

 

 

读已提交:

 

不可重复读: (隔离级别依然是读提交,虽然解决了脏读的问题,但又有了新问题)

 

可重复读:

 

幻读:(隔离级别依然是可重复读)

这个验证了我们上面的那个表:可重复读并不会发生幻读(innodb)

 

 

加餐

具了解
如果添加数据的话,会有一个临时表
事务的提交:提交临时表
事务的回滚:删除临时表
其他更多细节待后续再慢慢扣,水很深,还有什么tansaction_id、row_id

转载请注明:汪明鑫的个人博客 » 事务和隔离级别知识整理

喜欢 (1)

说点什么

3 评论 在 "事务和隔离级别知识整理"

提醒
avatar
排序:   最新 | 最旧 | 得票最多
kala
游客

楼主 mysql 默认隔离级别是repeable-read

汪明鑫
游客

不可重复读上面有个笔误,导致每次查询结果不一样。。。

wpDiscuz