数据库的事务 - 初遇事务一(极客时间)

初遇事务

在MySQL5.5以前, 默认的存储引擎是MyISAM, 在5.5版本以后默认存储引擎是InnoDB, 而这两个存储引擎的最大区别就在于InnoDB是支持事务的, 这也是InnoDB取代MyISAM的重要缘由. 什么是事务呢? 事务的英文是transaction, 也就是进行一次处理的基本单元, 要么彻底执行, 要么全都不执行.数据库

事务的特性: ACID

深刻理解事务, 就须要知道事务的四个特性, 那就是ACID:编程

  1. A, 也就会说原子性(Aomicity). 原子的概念就是不可分割, 能够理解为组成物质的基本单元, 也就是数据处理操做的基本单位.
  2. C, 就是一致性(Consistency), 一致性指的是数据库在进行事务操做后, 会有原来的一致状态, 编程另外一种一致状态. 也就是事务提交或回滚后, 数据库的完成性约束不能破坏.
  3. I, 就是隔离性(Isolocation), 指的是每一个事务都是彼此独立的, 不会受到其余事务的执行影响. 简单说就是一个事务在提交以前, 对其余事务都是不可见的.
  4. D, 就是持久性(Durability), 事务提交以后对数据的修改是持久性的, 及时在系统出故障的状况下(崩溃或存储介质发生故障), 数据的修改依然是有效地. 由于当事务完成以后, 数据库的日志就会被更新, 这个经过日志, 可让系统恢复到最后一次成功的更新状态.

这四个特性中, 原子性是基础, 隔离性是手段, 一致性是约束条件, 持久性是目的. 原子性和隔离性好理解, 至于一致性相对难, 笔者开始老是不知道这个一致性所说的状态是什么意思, 直到如今看了这个文档, 才发现.服务器

一致性自己是由具体的业务定义的, 任何写入数据库中的数据都须要知足咱们事先定义的约束规则, 到这里就能够理解一致性具体的含义了, 一致性其实说的是不违反约束规则, 好比主键约束, 惟一约束, 不为NULL约束等等.日志

另外一个持久性, 持久性是经过事务日志来保证的. 日志包括了回滚日志和重作日志. 经过事务对数据进行修改的时候, 首先会将数据库的变化信息记录到重作日志中, 而后再对数据库中对应的行进行修改, 这样作的好处是, 即便数据库崩溃, 数据库重启后也能找到没有更新到数据库系统中的重作日志, 从新执行, 从而使事务具备持久性.code

事务的控制

Oracle是支持事务的, 而在MySQL中, 须要选择合适的存储引擎才能够支持事务, 使用MySQL, 可使用SHOW ENGINES来查看当前MySQL支持的存储引擎, 以及该引擎是否支持事务.blog

事务经常使用的控制语句:事务

  1. START TRANSACTION或者BEGIN, 做用是显式开启一个事务.
  2. COMMIT: 提交事务, 提交事务后, 对数据库的修改是永久性的
  3. ROLLBACK或者ROLLBACK TO [SAVEPOINT], 回滚事务, 意思是撤销正在进行的全部没有提交的修改, 或者将事务回滚到某个保存点.
  4. SAVEPOINT: 在事务中建立保存点, 方便后续针对保存点进行回滚, 一个事务中能够存在多个保存点.
  5. RELEASE SAVEPOINT: 删除某个保存点
  6. SET TRANSACTION, 设置事务的隔离级别.

使用事务有两种方式, 一种是隐式事务, 一种是显示事务. 隐式事务其实就是自动提交. Oracle默认不自动提交, 须要手写COMMIT命令, 而MySQL默认自动提交, 可使用MySQL的命令来配置参数关闭自动提交:set autocommit = 0;是关闭自动提交, set autocommit = 1;是开启自动提交.ci

MySQL的默认状态下:文档

CREATE TABLE test(name varchar(255), PRIMARY KEY (name)) ENGINE=InnoDB;
BEGIN;
INSERT INTO test SELECT '关羽';
COMMIT;
BEGIN;
INSERT INTO test SELECT '张飞';
INSERT INTO test SELECT '张飞';
ROLLBACK;
SELECT * FROM test;

如今执行完的状况下, 数据库中默认保存了一条.

CREATE TABLE test(name varchar(255), PRIMARY KEY (name)) ENGINE=InnoDB;
BEGIN;
INSERT INTO test SELECT '关羽';
COMMIT;
INSERT INTO test SELECT '张飞';
INSERT INTO test SELECT '张飞';
ROLLBACK;
SELECT * FROM test;

如今数据库中应该是两条记录, 由于默认会隐式提交, 也就是在执行第一个INSERT INTO test SELECT '张飞';的时候, 执行完成就会提交, 只有在执行第二个的时候会产生主键冲突而回滚.

CREATE TABLE test(name varchar(255), PRIMARY KEY (name)) ENGINE=InnoDB;
SET @@completion_type = 1;
BEGIN;
INSERT INTO test SELECT '关羽';
COMMIT;
INSERT INTO test SELECT '张飞';
INSERT INTO test SELECT '张飞';
ROLLBACK;
SELECT * FROM test;

结果是一条数据, 很明显, 缘由是SET @@completion_type = 1;, 这个参数有3种可能:it

  1. completion=0, 这是默认状况, 也就是执行COMMIT会提交事务, 执行下一个事务前, 须要使用START TRANSACTION或者BEGIN来开启.
  2. completion=1, 这种状况下, 提交事务后, 至关于执行了COMMIT AND CHAIN, 也就是开启一个链式事务, 即当咱们提交事务以后会开启一个相同隔离级别的事务.
  3. completion=2, 这种状况下COMMIT=COMMIT AND RELEASE, 也就是当提交以后, 会自动与服务器断开链接.

这里使用了completion=1, 就是提交以后, 至关于在下一行写了START TRANSACTION 或 BEGIN, 这是插入两次张飞会被认为是在同一个事务以内的操做, 因此回滚以后, 数据库中就只有一条关羽的数据.

这个是事务的基本认识, 固然事务的隔离级别也很重要, 下一个随笔说.

相关文章
相关标签/搜索