| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> 事务隔离性(Isolation)介绍 -> 正文阅读 |
|
[大数据]事务隔离性(Isolation)介绍 |
一、概念介绍我们都知道,数据库的事务有ACID这4个需要具备的特性,本文主要介绍I即隔离性(Isolation)。 一个事务,就是一些对数据库的操作(增删改查)的组合,这个操作的组合需要满足ACID四个特性:
下面详细介绍隔离性,内容主要参考论文A Critique of ANSI SQL Isolation Levels。 二、隔离性实现问题上面说到,最理想的隔离性,就是等待一个事务执行完成后再执行另一个事务,同一个时间只有一个事务再执行,这样是最完美的隔离,这种实现方式一般叫做serial。而实现中,事务的执行是并行的,那么判断实现方式是否存在问题,就是与serial的实现方式进行比较,下面列出各种实现方式中可能出现的问题。 P0. Dirty Write
先说明一下符号代表的意思:
这个执行顺序的第一个问题是,两个事务执行完之后,可能部分数据是事务T1的,而部分数据是事务T2的。原本按照T1->T2或者T2->T1的顺序执行完,数据库状态应当是满足consistency的,但如果部分数据是T1的,部分数据是T2的,就不一定满足consistency了,例如需要满足x=y,而T1是执行(x=1,y=1),T2执行(x=2,y=2),最终x来自于T1,y来自于T2,那么结果就是(x=1,y=2),不满足x=y。 第二个问题是如果有事物需要abort时,例如 这个问题的解决方法,一般是使用Write Lock,一个事务T1对每个值进行修改之前,对这个值加上Write Lock,其他事务拿不到这个Write Lock,就只能阻塞住,等待T1进行commit或者abort时将锁释放掉。另外,Write Lock可能会造成Dead Lock,这需要一些措施去解决Dead Lock问题,本文就不展开将这个问题了。 另外一种方法是使用快照snapshot的数据库,也能解决这个问题。使用snapshot的数据库,会给事务分配一个开始时间Start_Timestamp,执行完成之后,提交时会分配Commit_Timestamp。 P1. Dirty Read
这个执行过程的问题,是T2读到了T1未提交的数据。 这个问题的第一个解决方式,是未进行commit的数据进行缓存,不写入到存储介质,也就不会被其他事务读取到。一般叫做READ COMMITTED。 还有lock方式就是加read lock,read与read可以并行,而如果有write正在进行,则read需要等待write完成;如果read正在进行,则write需要等待read完成。 还有snapshot方式,未提交的数据也是读取不到的(通过时间戳控制),所以就不存在这个问题了。 P2. Fuzzy Read(Non-Repeatable Read)
这个问题,典型的例子是一个事务读取两次x,两次读取中间有另一个事务执行了并执行完成,修改了x,那么就会导致这两次读取x的结果不同。这个问题针对的应该是READ COMMITTED,不能解决这个问题。 如果加了READ LOCK,这两个任务是无法并行的,也就没有这个问题。READ LOCK应该一定程度上就是为了解决这个问题而设计的。 而snapshot指定了timestamp,也不会有这个问题。 P3. Phantom
这个是广义的phatom(论文中定义),狭义的phatom:
这里新增了一个符号P,意思是一个条件,r1[P]就是T1读取满足条件P的内容,例如select count from xxx,调试就是xxx表。w2[y in P]意思就是T2新写入一个满足条件P的y。 这个问题的解决方法,一种是加gap锁,就是保证搜索出来的条目,它的上一条、下一条不会发生变化,如果条件是>、<或者==,那么gap锁住就会防止满足这个条件的条目发生变化。 使用snapshot也可以解决这个问题,因为指定了Start_Timestamp,新写入的数据并不会被这个事务读取到。但是对于广义的phantom,snapshot是解决不了的,例如: P4. Lost Update
这个问题是T2修改的数据被T1给覆盖掉了,例如T1执行x=x+1,T2执行x=x+2,那么按照上面这个流程去执行,最值只会得到T1执行后的结果就是x+1,但实际需要执行的应该是x+1+2,两个都要加上。 对于READ COMMITED,是有这个问题的。 对于加LOCK的,这个两个操作无法并行,不会出现这个问题。 而对于snapshot,如果不加修改的话,也是有这个问题的,snapshot本身并不限制这两个事务同时进行。snapshot解决这个问题,有几种方法,一种是事务T1执行commit时,检查在这个事务的Start_Timestamp到Commit_Timestamp之间是否有其他事务进行了commit,且与T1对同一个条目执行了write操作,如果有,则abort。第二种是rocksdb中的merge操作,就是将+1当作一个单独的记录,+2也当作一个单独的记录,那么操作执行完之后就有3条记录:x=10, x+1, x+2,去读取时将三条结合起来就能得到最终的结果。 A5A Read Skew
read skew是P2的一个更复杂的版本,类似的是在T1的执行过程中间,有一个任务T2修改了T1要读取的值,但read skew读取的是两个值x和y。 如果是加读写锁的方式,在r1[x]之后,拿到的读锁不释放,等待c1或者a1的时候再释放,那么w2[x]是无法执行的,T2会abort,那么就没有问题。 而snapshot的方式,r1[y]的时候,因为指定了Start_Timestamp,读取到的y是T2修改之前的,也没有问题。 A5B Write Skew
write skew也是约束的问题。例如要求x+y<=10,而我们进行这样的操作: 读写锁的方式,T1和T2是无法并发执行的,所以没有问题。 snapshot不能避免这个问题。 总结: |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 5:58:38- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |