当前位置: 移动技术网 > IT编程>数据库>Mysql > 数据库的事务 - 初遇事务一(极客时间)

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

2019年07月15日  | 移动技术网IT编程  | 我要评论
初遇事务 在MySQL5.5之前, 默认的存储引擎是MyISAM, 在5.5版本之后默认存储引擎是InnoDB, 而这两个存储引擎的最大区别就在于InnoDB是支持事务的, 这也是InnoDB取代MyISAM的重要原因. 什么是事务呢? 事务的英文是transaction, 也就是进行一次处理的基本 ...

初遇事务

在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约束等等.

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

事务的控制

oracle是支持事务的, 而在mysql中, 需要选择合适的存储引擎才可以支持事务, 使用mysql, 可以使用show engines来查看当前mysql支持的存储引擎, 以及该引擎是否支持事务.

事务常用的控制语句:

  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;是开启自动提交.

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种可能:

  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, 这是插入两次张飞会被认为是在同一个事务之内的操作, 所以回滚之后, 数据库中就只有一条关羽的数据.

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

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网