数据库事务

学习目的

  1. 了解事务的概念和特性
  2. 掌握Mysql事务的原理及使用
  3. 掌握解决Mysql事务并发引起的问题

一.事务

  1. 概念
    事务是数据库管理系统执行过程中最小的逻辑单元,一个事务是一个完整的业务逻辑单元,不可再分。事务由一个有限的数据库操作序列构成,是满足 ACID 特性的一组操作。
  2. 本质
    一个事务 = 一条DML语句。一组(多个) SQL语句组成一个业务逻辑,实现一个业务逻辑的多个事务要么同时全部成功,要么同时全部失败;一个业务逻辑的实现不允许出现一条SQL(事务)成功,一条失败。(若所有的业务都能使用1条DML语句完成,不需要事务机制)。
  3. 原理
    开启事务后,对于执行多个DML操作(insert、update、delete),只要没有提交事务,所有的DML操作都是暂时保存到"操作历史"(日志)当中,不会真正的参与到数据文件中。
  • 提交事务:将操作历史当中的所有DML操作同步序列化到数据文件当中,并清楚操作历史的DML;
  • 回滚事务:直接将操作历史当中的所有DML操作清楚,不与数据文件进行交流。
  1. 特性
  • 原子性Atomic:事务就是执行过程的最小逻辑单元,不可再分;
  • 一致性Consistency:事务必须保证多条DML语句同时成功或者同时失败;
  • 隔离性Isolation:事务与事务之间的执行互不影响,互不干扰;
  • 持久性Durability:事务中执行的最终数据必须持久化到硬盘文件中,事务才算成功的结束。
  1. 和事务相关的SQL语句
    与事务相关的SQL语句只有DML数据操纵语句(insert delete update),只有对表数据的增加、删除、更新才会出现安全问题,只读(select)语句不会发生数据安全问题。
  2. 事务出现的原因
    数据库自身存在约束:数据长度、主键唯一,用户自定义约束等影响了数据库中数据的安全。

1.1 事务控制语言TCL

  1. 概念
    事务控制语言全称Transaction Control Language,是SQL语言当中对事务进行控制的语句,主要的常用语句是commit(提交事务)和rollback(回滚事务)。
  2. 分类
  • commit:提交事务
  • rollback:回滚事务

二.事务并发问题

事务使用的经典业务场景:AOP,

2.1 丢失修改

2.2 读脏数据

2.3 不可重复读

  1. 概念
    不可重复读是指 在一个事务内,多次读同一数据(读取到的值不一样)。
  2. 原理
    在当前事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的前后两次读取数据之间,由于第二个事务的修改,第一个事务两次读到的的数据可能是不一样的。这样发生在一个事务内两次读到的 不一样的数据 称为不可重复读;本质是 原始读取的数据不可重复(不相同)
    例如,一个阅读者前后两次读取同一文档,但在前后分开的两次读取之间,作者重写了该文档,当编辑人员第二次读取文档时,文档已更改。如果在作者全部完成编写后编辑人员才可以读取文档,则可以避免该问题。
  3. 特点
    不可重复读的重点是修改,同样的条件,读取过的数据,再次读取出来的值不一样(不可以重复读取到相同的数据)。

2.4 虚读 / 幻读

  1. 概念
    虚读是指 当事务不是独立执行时发生的一种现象。
  2. 原理
    当一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。 同时,另一个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,就会发生第一个事务的用户发现表中 还有没有修改的数据行,就好象发生幻觉一样。
    例如,一个编辑人员更改作者提交的文档,但当生产部门将其更改内容合并到该文档的主复本时,发现作者已将未编辑的新材料添加到该文档中。 如果在编辑人员和生产部门完成对原始文档的处理之前,任何人都不能将新材料添加到文档中,则可以避免该问题。
  3. 特点
    幻读的重点在于新增数据或者删除数据,同样的条件,第 1 次和第 2 次读出来的数据个数(记录条数)不一样。

三.事务隔离级别(解决事务并发的方法)

  1. 概念
    事务的隔离级别是由于事务的隔离性特点而存在的,每一个隔离级别表示了事务之间不同的隔离层次,也因此导致事务之间的隔离性能不同。
  2. 分类
  • 第一级别:读未提交(read uncommitted)
  • 第二级别:读已提交(read committed)
  • 第三级别:可重复读(repeatable read)
  • 第四级别:串行化 / 序列化(serializable)
  1. 默认隔离级别
  • oracle默认隔离级别:第二级别 - - 读已提交。
  • mysql默认隔离级别:第三级别 - - 可重复读。

3.1 第一级别:读未提交(read uncommitted)

  1. 描述
    对方事务还没有提交,当前事务可以读取到对方未提交的数据。当对方事务对数据进行修改时,这种修改还没有提交到数据库中(仅保留在"操作历史"日志中),另外一个事务同时访问这个数据便产生了"脏数据",并使用了这个数据。
  2. 存在问题
    读未提交存在脏读现象(Dirty Read),表示读到了"脏"(未提交)的数据。
  3. 原理


    读未提交原理.png
  4. 演示
  • 开启两个窗口(同时开启两个事务)
  • 在同一个数据库下,针对同一个数据表进行操作演示事务
  • 设置两个事务的隔离级别都为第一级别--读未提交:set global transaction isolation level read uncommitted;
  • 查看事务的隔离级别:select @@global.tx_isolation;
  • 手动开启事务:start transaction;


    读未提交演示.png

3.2 第二级别:读已提交(read committed)

  1. 描述
    两个事务同时开启后,对方事务更新了数据,但还未提交,此时当前事务读取到的数据(条数)是更新之前的。在对方事务提交后,当前事务再次读取,此时读取到的就是对方事务提交后(更新后)的数据。
    在同一事务过程中,同一事物多次读取到的数据前后是不一致的(前面读取的数据总数或数据内容,和后面读取的数据总数或数据内容不相同),因此又叫"不可重复读"。
  2. 存在问题
    读已提交可以解决脏读现象,但读已提交存在不可重复读问题。
  3. 原理:事务之间隔离不可见
    事务2第一次读取id的value为Null,第二次读取id的value为2,两次读取的结果不相同。
    事务2第一次读取id的结果只有一个,而第二次读取id的结果有两个,第三次读取id的结果有三个,多次读取的结果(条数)不相同。
    读已提交原理.png
  4. 演示
  • 开启两个窗口(同时开启两个事务)
  • 在同一个数据库下,针对同一个数据表进行操作演示事务
  • 设置两个事务的隔离级别都为第一级别--读未提交:set global transaction isolation level read committed;
  • 查看事务的隔离级别:select @@global.tx_isolation;
  • 手动开启事务:start transaction;


    读已提交.png

3.3 第三级别:可重复读(repeatable read)

  1. 描述
    可重复读指的是在不同的时间,多次读取同一个数据库表,表的总记录数不变,前面一次读取多少条记录,后面也读取得到多少条记录。
    对于两个同时开启的事务,当前事务第一次读取得到表中的n条数据,对方事务在当前事务第一次读取后便删除表中的所有n条数据,并提交事务;
    当前事务再次(第二次)读取时,依然可以读取到和第一次读取时的n条数据。但是该n条理论上已被对方事务删除,当前事务应该读取到0条才对,但实际还是读出了n条。
    因此,虽然可以完成可重复读,但是可重复读取出来的是"假的"、"虚幻的"数据,称为"虚读"或"幻读"。
  2. 存在问题
    可重复读解决了"不可重复读"的问题,但是引起了虚读(幻读)的新问题。
  3. 原理


    可重复读.png
  4. 演示
  • 开启两个窗口(同时开启两个事务)
  • 在同一个数据库下,针对同一个数据表进行操作演示事务
  • 设置两个事务的隔离级别都为第一级别--读未提交:set global transaction isolation level repeatable read;
  • 查看事务的隔离级别:select @@global.tx_isolation;
  • 手动开启事务:start transaction;


    可重复读.png

3.4 第四级别:串行化 / 序列化(serializable)

  1. 描述
    事务串行化类似于线程并发同步。对于同时开启的多个事务,当前事务若正在执行中,其他事务必须等待,只有当前事务结束(提交或回滚),其他事务才能开启执行。不能在当前事务执行的期间强行插入,必须排队等候。
  2. 存在问题
    解决第一、第二、第三级别的所有存在问题,但由于需要排队执行,因此效率较低。
  3. 原理


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

推荐阅读更多精彩内容