mysql的事务性

(注:
一致性非锁定读(select * from table):读已提交会读取当前记录的最新快照,因此依然存在不可重复读的问题;可重复读会读取当前记录在事务开始时的快照,因此可以避免不可重复读的问题,但是由于没有加锁,依然存在幻读的问题

一致性锁定读(select * from table for update):读已提交会添加record lock,因此可以避免不可重复读的问题,但是存在幻读;可重复读会添加next-key lock,因此可以避免不可重复读和幻读的问题

数据库的事务性包括ACID四个方面:
A:Atomic原子性,对于数据库的事务性操作要么全部成功,要么全部失败
C:consistency一致性
I: Isolation隔离性,并发情况下的数据库事务之间应该相互隔绝,互不影响
D:Duration持久性,数据库事务执行之后,数据就被持久化到硬盘

要实现数据库的事务,主要需要关注两个问题:事务性并发处理

事务性

1.为保证性能,数据库中执行过的操作指令再在commit之后不会马上持久化到磁盘中,但假如数据库挂掉,会有一部分未持久化的数据丢失,为了保证数据的前后一致,数据库有了redo log。redo log在每次commit之后会都持久化到磁盘中,因此能够保证数据库在宕机时的数据正确性。
2.数据库事务执行过程中如果需要回滚,或者为了支持mvcc功能,数据库有了undo log

redo log和undo log

redo log,即重做日志,其作用为:当事务提交之后,记录修改的信息,保证事务的持久性。
mysql为了提升性能,不会在每次修改时都马上把数据同步到磁盘中,而是会维护一个缓冲池buffer pool,每次对数据库修改时,都会在缓冲池中缓存这次操作,而由一个后台线程做缓冲池与磁盘之间的同步。这就会导致一个潜在的问题:当缓冲池的信息没有被同步到磁盘,但是数据库却挂掉了时,缓冲池中的信息将会丢失。因此,为了保证这种情况下的数据一致性,数据库采用了redo log机制,
redo log机制包括redo log buffer和redo log两个模块,redo log buffer和上述的缓冲池一样处于内存当中,而redo log在磁盘中。事务中进行的修改操作都会被记录到redo log buf中,每次commit时,buffer中的内容都会持久化到磁盘中。因此。redo log会记录每一次成功操作的修改信息,并被持久化到磁盘中,当数据库挂掉时,系统会读取redo log恢复到最新数据。

redo log

redo log也会涉及到内存与磁盘之间的持久化,但是redo log的持久化性能优于数据,原因有两点:
1.redo log的持久化是顺序存储,数据库的缓存的持久化是随机存储;
2.缓存的同步以数据页为单位,每次传输的大小大于redo log;

总结:redo log的作用是为了保证已提交事务的一致性。
(注:数据库中还存在一种bin log,是用于数据库恢复全备文件以及主从复制的一种log。bin log和redo log看起来都是对数据进行备份,但是本质上存在很大的区别:
1.bin log是处于数据库上层的一种log,任何存储引擎对于数据库的修改都会产生bin log;而redo log仅针对innodb存储引擎;
2.两种log对于数据修改的内容形式不同,bin log记录的是执行的sql语句,如insert table ...,这是一种逻辑日志,不幂等,而redo log是记录的是对于每个页的修改结果,是一种物理日志,幂等
3.redo log在事务执行中不断被写入,而bin log只在事务完成时进行一次写入)

undo log,即回滚日志,其作用与redo log相反,为:在事务提交之前,记录修改的信息,保证事务的持久性。当事务需要回滚时,undo log可以保证恢复到事务开始时的状态。
每条数据变更操作都会对应一条undo log记录的生成,且回滚日志必须先于数据持久化到磁盘上;当事务需要回滚时,系统会根据回滚日志做逆向操作,即insert的逆向操作为delete,delete的逆向操作为insert,update的逆向操作为update
另外,undo log也提供了对mvcc功能的支持:假如事务A锁定并修改了记录行a,在提交之前,事务B又尝试读取行a,为了避免不可重复读,数据库会通过undo log保证事务B读到被修改前的行a,实现了非锁定的读取。

总结:undo log的作用是为了保证未提交事务的原子性。

并发处理

即在多个事务同时对数据库进行操作时,各个事务之间不能有影响,各个事务之间需要存在隔离性。为了保证并发时的隔离性,数据库采用了锁技术MVCC

mvcc

mvcc,即多版本并发控制。
当事务A想要访问一条记录,但是这条记录被事务B暂时锁定时,事务A不会等待事务B解锁,而是会读取记录的一个快照版本,这种方式被称为一致性非锁定读默认配置下,innodb是通过这种方式读取数据库数据的(可以通过配置,设置数据库读数据时必须加锁,这种方式被称为一致性锁定读)。而一个行记录可能会有多个快照数据,控制这些快照版本的技术即为mvcc。
总结:mvcc是innodb中控制数据的方式。

mysql的锁技术

锁技术

mysql的锁分为读锁和写锁两种:
读写,即共享锁(S Lock),多个读请求可以共享一把锁,不会造成阻塞;
写锁,即排他锁(X Lock),会排斥其他所有获取锁的请求,直到本次请求完成并释放了锁。


读写锁的兼容性

根据锁定的范围可以分为三类:
Record Lock:锁定单条记录;
Gap Lock:锁定范围,但不包括记录本身;
Next-Key Lock:锁定范围+锁定记录本身,相当与record lock+gap lock。

并发情况下的读写问题

数据库在并发的情况下,可能会出现三种可能的读写问题:脏读/不可重复读/幻读
****脏读****
当前事务读取到其他事务未提交的修改后数据,读到脏数据。
****不可重复读****
当前事务读取到其他事务已提交的修改后数据。如:

不可重复读

事务1在两次读取的时候读到的结果存在差异,因为事务2在两次操作之间对字段做了修改。不可重复读的重点在于数据是否被修改
****幻读****
当前事务对读取到的记录进行操作,但是读取之后操作之前这段时间内,该记录被其他事务删除或者新增了其他记录,导致后续的操作出错,这种现象叫做幻读
幻读

幻读的重点在于数据条目的删除或新增

隔离级别及原理

数据库的并发处理与其隔离性相关,mysql存在四个隔离级别:读未提交/读已提交/可重复读/串行化
读未提交
read uncommited,读未提交可以提升并发处理性能,能做到读写并行,但是会存在脏读等问题。

读已提交
read commited,事务读取或者修改记录时加record lock,因此不会出现不可重复读,但是可能出现幻读。

可重复读
repeatable read,事务读取或者修改记录时加next-key lock,因此可以避免幻读。

串行化
serialization,原理为:将所有操作变为串行。

总结case

事务A正在修改记录a(这里将a理解为单条或多条记录),会首先对a进行加锁,然后修改数据。事务结束之前,事务B:
1.想要读取记录a,事务B会通过mvcc读取到记录a之前的一个快照数据,而不会等待事务A对a进行释放;
2.想要修改记录a,在读已提交隔离级别下,事务A的加锁为record lock,事务B修改失败;在可重复读的隔离级别下,事务A的加锁为next-key lock,事务B修改失败;
3.想要新增a相关的记录(如在两条数据之间插入),在读已提交隔离级别下,事务A的加锁为record lock,事务B修改成功;在可重复读的隔离级别下,事务A的加锁为next-key lock,事务B修改失败。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容