MySQL事务
2021-08-23 17:33:27 1 举报
AI智能生成
MySQL事务
作者其他创作
大纲/内容
事务
ACID特性
在关系型数据库管理系统中,一个逻辑工作单元要成为事务,必须满足4个特性,即所谓的ACID
原子性 Atomicity
事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行
每一个写事务,都会修改BufferPool,从而产生相应的Redo/Undo日志,在BufferPool中的页被刷到磁盘之前,这些日志信息都会先写入到日志文件中,如果BufferPool中的脏页没有刷成功,此时数据库挂了,那在数据库再次启动之后,可以通过Redo日志将其恢复出来,以保证脏页写的数据不会丢失。如果脏页刷新成功,此时数据库挂了,就需要通过Undo来实现了
一致性 Consistency
指的是事务开始之前和事务结束之后,数据库的完整性限制未被破坏。
一致性包括两方面的内容
约束一致性
创建表结构时所指定的外键、Check、唯一索引等约束,MySQL不支持Check
数据一致性
是一个综合性的规定,因为它是原子性、持久性、隔离性共同保证的结果,而不是单单依赖于某一种技术
一致性可以理解为数据的完整性,它是通过原子性、隔离性、持久性来保证的,而这3个特性又是通过Redo/Undo来保证的
逻辑上的一致性,包括唯一索引、外键约束、Check约束,这属于业务逻辑范畴
隔离性 Isolation
指的是一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对其他的并发事务是隔离的
InnoDB支持的隔离性有4种,隔离性由低至高分别为:读未提交、读提交、可重复读、可串行化
锁和多版本控制(MVCC)技术就是用于保障隔离性的
持久性 Durability
指的是一个事务一旦提交,它对数据库中数据的改变就应该是永久性的,后续的操作或故障不应该对其有任何影响,不会丢失
MySQL一个“提交”动作触发的操作有,它们都是数据库保证其数据完整性、持久性的手段
binlog落地
发送binlog
存储引擎提交
flush_logs
check_point
事务提交标记
MySQL的持久性与WAL技术相关,redo_log在系统Crash重启之类的情况时,可以修复数据,从而保障事务的持久性
通过原子性可以保证逻辑上的持久性,通过存储引擎的数据刷盘可以保证物理上的持久性
ACID中有3个与WAL有关系,都需要通过Redo、Undo日志来保证
WAL:Write-Ahead Logging,先写日志,在写磁盘
事务的演化
并发事务
事务并发处理可能会带来一些问题
更新丢失
当两个或多个事务更新同一行记录,会产生更新丢失现象,可以分为回滚覆盖和提交覆盖
回滚覆盖
一个事务回滚操作,把其他事务已提交的数据给覆盖了
提交覆盖
一个事务提交操作,把其他事务已提交的数据给覆盖了
脏读
一个事务读取到了另一个事务修改但未提交的数据
不可重复读
一个事务中多次读取同一行记录不一致
幻读
一个事务多次按照相同条件查询,查询结果不一致
演化
排队
最简单的方法,就是完全顺序执行所有事务的数据库操作,不需要加锁,简单地说就是全局排队
序列化执行所有的事务单元,数据库某个时刻只处理一个事务操作,特点是强一致性,处理性能低
排他锁
引入锁之后就可以支持并发处理事务,如果事务之间涉及到相同的数据项时,会使用排他锁,或叫互斥锁,先进入的事务独占数据项以后,其他事务被阻塞,等待前面的事务释放锁
读写锁
读写锁就是进一步细化锁的颗粒度,区分读操作和写操作,让读和读之间不加锁
读写锁,可以让读和读并行,而读和写、写和读、写和写这几种之间还是要加排他锁
MVCC
概念
多版本控制,也就是Copy on Write的思想
在事务A开始写操作的时候会Copy一个记录的副本,其他事务读操作会读取这个记录副本,因此不会影响其他事务对此记录的读取,实现写和读并行
MVCC除了支持读和读并行,还支持读和写、写和读的并行,但为了保证一致性,写和写是无法并行的
MVCC(Multi_Version_Concurrency_Control)被称为多版本控制,是指在数据库中为了实现高并发的数据访问,对数据进行多版本处理,并通过事务的可见性来保证事务能看到自己应该看到的数据版本
多版本控制很巧妙地将稀缺资源的独立互斥转换为并发,大大提高了数据库的吞吐量及读写性能
如何生成多版本
每次事务修改操作之前,都会在Undo日志中记录修改之前的数据状态和事务号,该备份记录可以用于其他事务的读取,也可以进行必要时的数据回滚
实现原理
最大的好处是读不加锁,读写不冲突
在读多写少的系统应用中,能极大的提升系统的并发性能
目前MVCC只在Read Commited和Repeatable Read两种隔离级别下工作
MVCC并发控制中,读操作可分为
快照读 Snapshot Read
读取的是记录的快照版本,不用加锁
当前读 Current Read
读取的是记录的最新版本,并且当前读返回的记录,都会加锁,保证其他事务不会再并发修改这条记录
MVCC实现了读读、读写、写读并发处理,如果想进一步解决写写冲突,可以采用以下方案
乐观锁
悲观锁
事务隔离级别
MySQL数据库系统提供了4种隔离级别
读未提交
Read UnCommitted,所有事务都可以看到其他未提交事务的执行结果
解决了回滚覆盖类型的更新丢失,但可能发生脏读现象,也就是可能读取到其他会话中未提交事务修改的数据
已提交读
Read Committed,一个事务只能看到其他事务已提交的数据
解决了脏读,但可能发生不可重复读,即一个事务中两次查询结果不一致
大多数数据库系统的默认隔离级别(非MySQL默认)
可重复读
Repeatable Read,确保同一事务的多个实例在并发读取数据时,会看到同样的数据行
解决了不可重复读,理论上会出现幻读,InnoDB通过MVCC机制解决了该问题
MySQL默认事务隔离级别
可串行化
Serializable,所有增删改查串行执行。强制事务排序,使之不可能互相冲突
这个级别可能导致大量的超时现象和锁竞争,效率低下
最高的隔离级别
数据库的事务隔离级别越高,并发问题就越小,但并发处理能力越差
RU隔离级别最低,并发问题多,但并发处理能力好
对不可重复读和幻读并不敏感,更多关心并发处理能力,可以使用RC隔离级别
隔离级别和锁
事务隔离级别是SQL92定制的标准,详单与事务并发控制的整体解决方案,本质上是对锁和MVCC使用的封装,隐藏了底层细节
锁是数据库实现并发控制的基础,事务隔离性是采用锁来实现,对相应操作加不同的锁,就可以防止其他事务同时对数据进行读写操作
对用户来说,首先选择使用隔离级别,当选用的隔离级别不能解决并发问题或需求时,才有必要在开发中手动的设置锁
关系
RU级别
读操作不加S锁
RC级别
读操作需要加S锁,但是查询语句执行完以后立即释放S锁
RR级别
读操作需要加S锁,但是事务提交之前并不释放S锁,必须等事务结束才释放
Serializable
会在RR级别基础上,添加一个范围锁,保证一个事务在两次查询时结果相同
默认
MySQL:RR
Oracle、SQLServer:RC
一般使用时,建议采用默认隔离级别,然后存在的一些并发问题,可以通过悲观锁、乐观锁等实现处理
控制
查看
show variables like ‘%isolation%’;
select @@tx_isolation;
0 条评论
下一页