使我郁郁寡欢的 MySQL 事务和锁

一 事务的ACID 特性

事务是一组 SQL 语句,它们是一个执行单位。

1 原子性(Atomicity)与 持久性(Durability)

原子性:单个事务的 SQL 要么全都执行成功,要么全部执行失败。 事务的原子性通过 Undo Log 日志实现。
持久性:一个事务一旦提交,它对数据库中数据的改变是永久性的。事务的持久性通过 Redo Log 日志实现。
 

1.1 Undo Log 

Undo :意为撤销或取消,以撤销操作为目的,返回某个指定的状态。
 
Undo Log :数据库事务开始之前,会将要修改的记录存放到 Undo 日志里,当事务回滚时或者数据库崩溃时,可以利用 Undo 日志,撤销未提交事务对数据库产生的影响。
 
Undo Log  产生和销毁: Undo Log  在事务开始前产生;事务在提交后,并不会立刻删除 U ndo Log,I nnodb  会将该事务对应的 U ndo Log  放入到删除列表中,后面会通过后台线程P urge Thread  进行回收处理。Undo Log  属于逻辑日志,记录一个变化过程。例如执行一个  delete ,Undo Log 会记录一个  insert ;执行一个  update ,Undo Log 会记录一个相反的 update
 

1.2 Redo Log

Redo:顾名思义就是重做。以恢复操作为目的,在数据库发生意外时重现操作。

Redo Log:事务中修改的任何数据,都会将最新的值备份存储到 Redo Log。Redo Log 可以防止在发生故障的时间点,尚有脏数据未写入磁盘中,重启 MySQL 服务的时候,根据 Redo Log 进行重做,从而达到事务的未入磁盘数据进行持久化这一特性。

Redo Log 的生成和释放:随着事务操作的执行,就会生成  Redo Log ,在事务提交时会将产生 Redo Log 写入 Log Buffer ,并不是随着事务的提交就立刻写入磁盘文件。等事务操作的脏页写入到磁盘之后,Redo Log 的使命也就完成了, Redo Log  占用的空间就可以重用(被覆盖写入)。
 

1.3 图解

(1)流程图

(2)Redo Undo 写入过程

(3)数据持久化到磁盘

通过变量 innodb_flush_log_at_trx_commit 的值来决定。该变量有3种值:0、1、2,默认为1。这个变量只是控制 commit 动作是否刷新 Log Buffer 到磁盘

(1)0,事务提交后,每秒将 Redo buffffer 写入 OS cache, 再调用 fsync() 把 OS cache 写入磁盘;

(2)1,事务每次提交都会将 Redo buffffer 写入 OS cache, 再调用 fsync() 把 OS cache 写入磁盘;

(3)2,事务每次提交仅将 Redo buffffer 写入 OS cache,然后由后台 Master 线程每隔 1s 调用 fsync() 把 OS cache 写入磁盘。

一般建议选择取值2,因为 MySQL 挂了数据没有损失,整个服务器挂了才会损失1秒的事务提交数据。

 

2 一致性(Consistency)

mysql事务“一致性”理解

3 隔离性(Isolation)

 
隔离型指事务之间不互相影响,这样事务在并发执行时会得到与串行执行一样的效果。
 

3.1 没有隔离级别可能会产生的问题

(1)脏读(数据在修改)

某个事务所做的修改尚未提交时,其他事务就能读到这些修改。

(2)幻读(数据在增加)

一个事务突然读到之前未见过的行。假设某个事务刚执行完一条 SELECT 语句,接着另一个事务插入了一条新的记录,此时第一个事务再执行一条 SELECT 语句时,就有可能看到这条新增的记录。

(3)不可重复读

同一个事务使用同一条 SELECT 在每次读取时得到的结果都不一样。
 
(4)数据覆盖
 
回滚覆盖:一个事务回滚操作,把其他事务已提交的数据给覆盖了。
提交覆盖:一个事务提交操作,把其他事务已提交的数据给覆盖了。


3.2 隔离级别

(1)READ UNCOMMITTED

允许某个事务看到其他事务尚未提交的行修改。

(2)READ COMMITTED

允许某个事务看到其他事务已经提交的行修改。

(3)REPEATABLE READ(MySQL默认隔离级别 )

同一个事务使用同一条 SELECT 在每次读取时得到的结果都一样,就算中间有其他事务插入或修改行。

(4)SERIALIZABLE

如果某个事务在读取某些行,那么在它完成之前,其他事务都无法对这些行进行修改。

3.3 MySQL隔离级别控制

3.3.1 查看事务隔离级别

show variables like 'transaction_isolation'; 

select @@transaction_isolation;

3.3.2 设置事务隔离级别

set transaction_isolation='READ-UNCOMMITTED'; 
set transaction_isolation='READ-COMMITTED'; 
set transaction_isolation='REPEATABLE-READ'; 
set transaction_isolation='SERIALIZABLE';

二 锁分类

根据操作粒度来分:表级锁和行级锁

根据操作类型来分:读锁(共享锁)和写锁(排他锁)222

根据操作性能来分:乐观锁和悲观锁

 

 

 

 

 

 

 

相关推荐
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页