mysql第一篇

一、mysql的事物隔离级别

mysql事务都是指在InnoDB引擎下,MylSAM引擎是不支持事务的
事务的特性ACID:原子性、一致性、隔离性、持久性
sql标准定义了四种隔离级别,MYSQL全都支持:1、读未提交ru 2、读提交rc 3、可重复读rr 4、串行化 。隔离强度逐渐增强,性能逐渐变差,可重复读是mysql的默认级别。django的orm是设置了读提交。事务的额隔离是为了解决脏读、不可重复度、幻读等问题

在这里插入图片描述
相关命令

# 查看事务隔离级别
show variables like 'transaction_isolation';
select @@transaction_isolation    # tx_isolation (mysql5.7.20之后)
# 修改数据库的隔离级别
set 作用域 transaction isolation level 事务隔离级别
set session/global transaction isolation level read uncommitted/read committed/repeatable read/serializable
# 其中作用域:session只针对当前会话窗口;global是全局的
set global transaction isolation level read committed # 设置全局隔离级别为读写提交级别

mysql执行事务流程

begin/start transation开始,然后执行一系列操作,最后执行commit操作,事务才结束。当然,如果进行回滚操作(rollback),事务也会结束
注意:begin命令不代表事务的开始,事务开始于begin命令之后的第一条语句执行的时候
begin;
select * from xxx;   # 代表事务的开始
commit; # rollback

# 查询当前有多少事务正在运行
select * from information_schema.innodb_trx;

重点:分析4个隔离级别

read uncommitted:mysql事务隔离其实是依靠锁来实现的,加锁会带来性能的损失。读未提交隔离级别是不加锁的,所以它的性能最好。但是它连脏读都无法解决,比如启动两个事务A和B,当事务B在修改数据后未提交时,并且之后做了回滚操作。而事务A拿着修改的数据进行相关操作,而这些数据此时已经是脏数据
读未提交,其实就是可以读到其他事务未提交的数据,但没有办法保证你读到的数据最终一定是提交后的数据,如果中间发生回滚,那就会出现脏数据问题,读未提交没办法解决脏数据问题。更别提可重复读和幻读了

read committed:读提交就是一个事务只能读到其他事务已经提交过的数据,也就是其他事务调用commit命令之后的数据,能解决脏数据的问题,但是无法做到可重复读以及解决幻读。比如,两个事务A和B,当事务A使用update语句将age=1字段改成age=10,事务B用select语句查询,发现在事务A未提交之前age=1,一旦事务A提交,事务B查询的age就是10,所以在同一事务中,事务的不同时刻同样的查询条件,查询出的记录内容是不一样,事务A的提交影响了事务B的查询结果,这就是不可重复读,也就是读提交隔离级别。
读提交事务隔离级别是大多数流行数据库的默认事务隔离界别,比如 Oracle,但是不是 MySQL 的默认隔离界别。

repeatable read:事务不会读到其他事务对已有数据的修改,即使其他事务已提交。也就是说,事务在开始读到的已有数据是什么,直到本事务提交前的任意时刻,这些数据的值都一样。但是对于其他事务新插入的数据是可以读到的,这就引发了幻读问题(幻读和不可重复读的区别:前者能读出数据行数变化,后者是读出数据变化)。

串行化:相当于单线程,后一个事务的执行必须等到前一个事务结束。隔离效果最好,效率最差。

二、msql中是如何实现事务隔离的

1、名词解释

# 快照
可重复读是在事务开始的时候就生成一个当前事务全局性的快照,而读提交则是每次执行语句的时候都重新生成一次快照
# 遵循以下规则
1、当前事务内的更新,可以读到;
2、版本未提交,不能读到;
3、版本已提交,但是却在快照创建后提交的,不能读到;
4、版本已提交,且是在快照创建前提交的,可以读到;
# 行锁
执行update操作要对修改的行加行锁,这个行锁会在事务提交之后才释放,而在事务提交之前,其他事务申请不到行锁,会一直处于等待状态,若等待时间过长会出现超时异常
# 间隙锁
区间范围内加锁

2、实现可重复读

为了实现可重复读,MYSQL采用了MVVC(多版本并发控制)的方式
我们在数据库表中看到的一行记录可能实际上有多个版本,每个版本的记录除了有数据本身外,还要有一个表示版本的字段,记为 row trx_id,而这个字段就是使其产生的事务的 id,事务 ID 记为 transaction id,它在事务开始的时候向事务系统申请,按时间先后顺序递增。
解决并发写问题使用行锁
解决幻读的问题使用间隙锁
mysql把行锁和间隙锁合并在一起,解决了并发写和幻读的问题,这个锁叫做 Next-Key锁。

三、总结

MySQL 的 InnoDB 引擎才支持事务,其中可重复读是默认的隔离级别。

读未提交和串行化基本上是不需要考虑的隔离级别,前者不加锁限制,后者相当于单线程执行,效率太差。

读提交解决了脏读问题,行锁解决了并发更新的问题。并且 MySQL 在可重复读级别解决了幻读问题,是通过行锁和间隙锁的组合 Next-Key 锁实现的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值