MySQL事务的概念以及处理方式

MySQL事务主要用来处理数据量大、数据复杂度高的数据操作,最经典的使用场景是银行的转账:需要先从银行账户A中取出钱,然后再存入银行账户B中,如果中间出现问题,而没有事务的保证,那么就会出现B收不到钱,而A支出钱又回不到自己的账户的严重问题,那么有了事务机制,这个问题就解决了。

定义

事务(transaction) :全有或全无的操作,是几个操作组合要么全部发生要么全部不发生的工作单元。

事务的 ACID 特性

在软件开发中,一般用一个术语描述事务:ACIDACID 表示 4 个特性。

  • Atomic 原子性:确保事务中的所有操作全部发生或全部不发生。如果所有的活动都成功了,事务也就成功了。如果任意一个活动失败了,整个事务也失败回滚了。
  • Consistent 一致性:一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态。现实的数据不应该被损坏。
  • Isolated 隔离性:多个用户对相同的数据进行操作,每个用户的操作不会与其他用户纠缠在一起。避免发生同步读写相同数据的事情(注意的是,隔离性往往涉及到锁定数据库的行或表,会牺牲速度)
  • Durable 持久性:事务完成后结果应该持久化,能从任何系统崩溃中恢复过来。一般就是将结果存储到数据库中。

当任意一个步骤失败时,所有步骤的操作结果都会被取消,从而保证了事务的原子性 。原子性 通过保证系统数据永远不会处于不一致或部分完成的状态来确保一致性 。隔离性同样确保了一致性 。最后,所有结果是持久化 的,提交到数据存储中。在发生系统崩溃或其他灾难性事情的时候,不用担心事务的结果丢失。

事务的隔离

1. 并发时遇到的问题

在事务并发操作时,经常出现一些问题,这些问题可用几个术语名词描述:

  • 脏读
    一个事务读取了另一个事务并发写的未提交的数据,比如:事务A读取了事务B写入的数据,但是B事务并未提交,后来其撤销了修改,此时事务A就读取了不该读取的数据。
  • 幻读
    一个事务重复读取数据,在获得的数据行中发现某些数据是其它事务最近操作的数据,比如:事务A反复执行查询语句查询数据表,而这时另一事务B正在操作该表,恰好的是事务B操作的数据正符合事务A查询的条件,而事务A再读取时,发现结果集发生了变化,这在并发事务时经常出现。
  • 不可重复读
    一个事务重复读取之前读取过的数据,后发现读取的数据被另一个事务所修改,比如:事务A反复读取指定的数据,而此时事务B正好操作该数据,当事务A再次查询时,发现之前读取的数据已经变化。
    Note: 上面事务并发出现的问题,可以通过设置事务的隔离来处理,但不能完全依赖事务隔离,而是应该在应用程序中恰当的使用锁来控制并发访问,两者的结合是解决的问题关键。

2. 事务的隔离级别

事务隔离级别分为4种:

隔离级别 含义 可能导致
ISOLATION_DEFAULT 使用后端数据库默认的隔离级别 稍微长一点的文本
ISOLATAION_READ_UNCOMMITTED 未提交读 允许读取尚未提交的数据变更 脏读、不可重复读、幻读
ISOLATION_READ_COMMITTED 已提交读 允许读取并发事务已经提交的数据 不可重复读、幻读
ISOLATION_REPEATABLE_READ 可重复读 对同一字段的多次读取结果是一致的,除非数据是被本事务自己所修改 幻读
ISOLATION_SERIALIZABLE 可串行化 完成服从 ACID 隔离级别,确保阻止脏读、不可重复读、幻读。这是最慢的事务隔离级别,因为它通常是通过完全锁定事务相关的数据库来实现的

MySQL 事务

MySQL 数据库中,并不是所有引擎都支持事务,常用的引擎 InnoDB 和 MyISAM 中仅有 InnoDB 支持事务。
MySQL 一般过程:

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

START TRANSACTION;
    SAVEPOINT step0;
    INSERT INTO new_student (name, age) VALUES ('aaa', 1),('bbb',2); 
    INSERT INTO new_student (name, age) VALUES ('ccc', 3),('ddd',4);
    
    SAVEPOINT step1;
    UPDATE new_student SET age = 100 WHERE name = '张三';

    ROLLBACK TO step1;

事务语法

  • SET TRANSACTION:用来设置事务的隔离级别。InnoDB 存储引擎提供事务的隔离级别有 READ UNCOMMITTED 、READ COMMITTED 、REPEATABLE READ 和 SERIALIZABLE 。
  • BEGIN 或START TRANSACTION:显示地开启一个事务。
  • SAVEPOINT <identifier>:SAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT。
  • RELEASE SAVEPOINT <identifier>:删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常。
  • COMMIT:也可以使用COMMIT WORK ,不过二者是等价的。COMMIT 会提交事务,并使已对数据库进行的所有修改称为永久性的。
  • ROLLBACK:有可以使用ROLLBACK WORK ,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。
  • ROLLBACK TO <identifier>:把事务回滚到标记点。

1. 设置事务隔离级别

在编写事务时,第一步是要确定事务的隔离级别是什么。使用以下语法设置:

SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL 
{READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}
  • 默认为空(不带 SESSION 和 GLOBAL):为下一个(未开始)事务设置隔离级别。
  • GLOBAL:语句在全局对从那点开始创建的所有新连接(除了不存在的连接)设置默认事务级别。你需要SUPER权限来做这个。
  • SESSION:为将来在当前连接上执行的事务设置默认事务级别。 任何客户端都能自由改变会话隔离级别(甚至在事务的中间),或者为下一个事务设置隔离级别。

2. 开始事务

开始一个 MySQL 的事务有两种方法:

  • 用 BEGIN 或START TRANSACTION显示地开启一个事务。当遇到 COMMIT 或 ROLLBACK 时,结束该事务。
  • 用 SET 来改变 MySQL 的自动提交模式。MySQL 默认是自动提交的,但可以通过 SET autocommit = 0, 禁止自动提交。但注意当你用 SET autocommit = 0的时候,以后所有的SQL都将做为事务处理,直到你用 COMMIT 确认或 ROLLBACK 结束,当结束这个事务的同时也开启了个新的事务!按第一种方法只将当前的作为一个事务!

3. 设置以及释放 SAVEPOINT

保留点 SAVEPOINT 是为事务在执行过程中提供一个备份。当事务庞大时,保留点就显得格外有效。
一般的 ROLLBACK 是回滚整个事务,而使用 ROLLBACK TO SAVEPOINT 可以指定回滚到具体某一步。一来省去很多保留点之前的操作,二来更为灵活。
释放保留点 RELEASE SAVEPOINT <identifier> 是释放 SAVEPOINT ,保留点在事务处理完成后(无论是 COMMIT 或 ROLLBACK )就会自动释放,无需自己释放。

4. 回滚 ROLLBACK

回滚就是恢复到事务执行之前,或者是恢复到 SAVEPOINT 所指向的某一步。
但是,并不是所有的 SQL 命令都是可以回滚的。有些 SQL 命令是包含隐式提交的,则无法回滚。具体有:

  • DDL语句:ALTER DATABASE 、ALTER EVENT 、ALTER PROCEDURE 、ALTER TABLE 、ALTER VIEW 、CREATE TABLE 、DROP TABLE 、RENAME TABLE 、TRUNCATE TABLE 等;
  • 修改 MySQL 架构的语句:CREATE USER 、DROP USER 、GRANT 、RENAME USER 、REVOKE 、SET PASSWORD ;
  • 管理语句:ANALYZE TABLE 、CACHE INDEX 、CHECK TABLE 、LOAD INDEX INTO CACHE 、OPTIMIZE TABLE 、REPAIR TABLE 等。

参考链接:https://www.jianshu.com/p/3a73cee85b6d
https://blog.csdn.net/why_2012_gogo/article/details/50953747

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

推荐阅读更多精彩内容