我理解的数据库事务

一、最简单的例子来说明事务

“A账户向B账号汇钱”来说明事务

1、从A账号中把余额读出来。
2、对A账号做减法操作。
3、把结果写回A账号中。
4、从B账号中把余额读出来。
5、对B账号做加法操作。
6、把结果写回B账号中。

为了数据的一致性,这6件事,要么都成功做完,要么都不成功。而且这个操作的过程中。对A、B找好的其他访问必须锁死,所谓锁死就是要排除其他的读写操作,不然会有脏数据问题,这就是事务。

二、数据库事务特性

  • Atomic(原子性)

    事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。事务的原子性也体现在事务对数据的读取上,例如一个事务对同一数据项的多次读取的结果一定是相同的。

  • Consistency(一致性)

    只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初的状态。
    事务需要保持数据库的正确性、完整性和一致性。
    有些时候这种一致性由数据库的内部规则保证,例如数据的类型必须正确,数据值必须在规定的范围内,等等。
    另外一些时候这种一致性由应用保证的,例如,** 一般情况下银行账务余额不能是负数,信用卡消费不能超过该卡的信用额度等。**

  • Isolation(隔离性)

    事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性。
    同时,并行事务的修改必须与其他并行事务的修改相互独立。
    事务的隔离性一般由事务的锁来进行控制。

    许多时候数据库在并发执行多个事务,每个事务可能需要对多个表进行修改和查询,与此同时,更多的查询请求可能要在执行。数据库需要保证每一个事务在它的修改全部完成之前,对其他的事务是不可见的。

    换句话说,不能让其他事务看到该事务的中间状态,例如,从银行账户A转一比款项a到账户B,不能让其他事务(例如账户查询)看到A账户已经扣除款项a但B账户却没有增加款项a的状态。

  • Durability(持久性)

    事务结束后,事务处理的结果必须能够得到固化,即使系统出现各种异常也是如此。

三、数据库的隔离级别

由于性能的考虑,许多数据库允许使用牺牲隔离属性来换取并发度,从而获取性能的提升。

  • Read uncommitted(RU):读取未提交的数据(未授权读取),即其他事务已经修改单未commit的数据,这是最低的隔离级别。允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。

  • Read committed(RC):允许不可重复读取,在一个事务中,对同一个项,前面的读取跟后面的读取结果可能不一样。例如第一次读取时另一个事务的修改还没有提交,第二次读取时已经提交了。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。

  • Repeatable read(RR):可重复读取,在一个事务中,对同一个项,前面的读取跟后面的读取结果一样。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。

  • Serializable(S):可序列化,即数据库的事务市可串行化执行的,就像一个事务执行的时候没有别的事务同时在执行,这是最高的隔离级别。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。

隔离级别的降低可能导致读取到脏数据或事务执行异常

  • Lost update(LU) :两个事务同时修改一个数据项,但后一个事务中途失败退出,则对数据项的两个修改可能都丢失。

  • Dirty Reads(DR): 一个事务读取某数据项,但另一个事务更新了此数据项却没有提交,这样所有的操作可能都得回滚。

  • Non-repeatable Reads(BRR):一个事务对同一数据项的多次读取可能得到不同的结果。

  • Second lost updates problem(SLU):无法重复读取的特例,两个并发事务同时读取和修改同一数据项,则后面的修改可能使得前面的修改失效。

  • Phantom Reads(PR):也称为幻读,例如在事务执行过程中,由于前面的查询和后面的查询的期间有另外一个事务插入数据,后面的查询结果中未出现的数据。

隔离级别与读写异常(不一致)的关系如下

LU DR NRR SLU PR
RU Y Y Y Y Y
RC N N Y Y Y
RR N N N N Y
S N N N N N

四、数据库的事务与线程相似的地方

  • 线程之间共享同一片资源,而事务共享的则是数据库内部的数据
  • 多线程的意义在于并发执行,提高效率;事务并发执行也能提高程序与数据库交互的效率。

五、用例子来说明事务隔离性

假设账户A有1000元,B有1000元,C有1000A

1、操作员u1执行一次转账事务m1
从A转移500元到B,再从A的余额中转移50%元平均分配到 A B C D E余额中

2、操作员u2执行一次转账事务m2
从B转移1000元到A

3、操作员u3执行一次转账事务m3
从A转移200元到B

4、操作员u4开户D

账户表为T_C,其包含字段为 账户名称cname 余额money

记录为{A,1000},{B,1000}

事务m1的操作包括

  读A,读B,   
  写A,写B,   
  提交AB,读A,   
  读C,写C,写C,   
  提交AC   

事务m2的操作包括

  读B,读A,   
  写B,写A,   
  提交AB   

事务m3的操作包括

    读A,读B,   
    写A,写B,   
    提交AB   

事务m4的操作包括

    写D,   
    提交D   

1.若未授权读取ReadUncommitted

m1读A,B,写了A但没写B
此时m2不可以写B,可以读取AB,但是B是脏读。
隔离级别使用了“排他写锁”。

2.若授权读取ReadCommitted

m1读A,B,写了A但没写B
此时m2不可以写B,可以读取A,不能读取B,因为B是脏读。
隔离级别使用了“排他写锁”。
m1读写了A,B,提交A``B,
m3提交了A``B 此时m1准备第二次A是允许的。
隔离级别使用了“瞬间共享读锁”。
(但由于第二次读产生了不可重复读的问题,事务1脱力了元自行,因为逻辑上看事务1中被插入了3,影响了A的余额50%的计算。)

3.若可重复读取RepeatableRead

m1读A,B,写了A
但没写B此时m2不可以写B,可以读取A,不能读取B,因为B是脏读。
隔离级别使用了“排他写锁”。
m1读写了A,B,提交A``B,
m4提交了D此时m3是能读不能写A并更新提交的。
此时m4是能读能能插入D的。隔离级别使用了“共享读锁”。
(和ReadCommitted比RepeatableRead区别对已经提交的事务可以进行读,但不能写,但是同一张表可以插入新的记录。)

4.序列化Serializable

任何事务都只能等前一事务完全执行完再执行。 但是失去了并发性。

转载,有修改,我只是个搬运工

参考

事务的ACID
分布式系统的事务处理
关于数据库事务、隔离级别、锁的理解与整理

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

推荐阅读更多精彩内容