事务

1.事务概述

事务是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。事务用来保证数据库的完整性——要么都做修改,要么都不修改。
事务具有以下四个特性(ACID):
(1)原子性(Atomicity)
原子性是指整个数据库事务是不可分割的工作单位。只有使事务中所有的数据库操作执行都成功,才算整个事务成功。如果事务中任何一个SQL语句执行失败,那么已经执行成功的SQL语句也必须撤销,数据库状态应该回退到执行事务之前的状态。
原子性由数据库的事务管理部件保证。
(2)一致性(Consistency)
一致性是指事务将数据库从一种状态转变为下一种一致的状态。在事务开始之前和事务结束之后,数据库的完整性约束没有破坏。
一致性由应用程序员保证。
(3)隔离性(Isolation)
隔离性是指一个事务的影响在该事务提交之前对其他事务都不可见。
隔离性由数据库的并发控制部件保证。
(4)持久性(Durability)
持久性是指事务一旦提交,其结果是永久性的。即使发生宕机等故障,数据库也能将数据恢复。
持久性由数据库的恢复管理部件

2.事务的实现

事务的隔离性是由锁得以实现的。事务的原子性、一致性、持久性通过数据库的redo和undo来完成。

2.1 redo

在InnoDB引擎中,事务日志是通过重做(redo)日志文件和InnoDB存储引擎的日志缓冲(InnoDB Log Buffer)来实现。
redo过程:

     当开始一个事务时,会记录该事务的一个LSN(Log Sequence Number,日志序列号);当事务执行时,会往InnoDB存储引擎的日志缓冲里插入事务日志;当事务提交时,必须将InnoDB存储引擎的日志缓冲写入磁盘(默认的实现,即innodb_flush_log_at_trx_commit=1)。也就是写数据前,先写日志。这种方式称为预写日志方式(Writer-Ahead Logging,WAL)。
      InnoDB存储引擎通过预写日志的方式来保证事务的完整性,这意味着磁盘上存储的数据页和内存缓冲池中的页是不同步的,对于内存缓冲池中页的修改,先是写入重做日志文件,然后再写入磁盘,因此是一种异步的方式。
      可以通过show engine innodb status来观察当前磁盘和日志的差距。

2.2 undo

重做日志记录了事务的行为,可以很好地通过其进行“重做”。但是事务有时还需要撤销,这时就需要undo。undo与redo正好相反,对于数据库进行修改时,数据库不但会产生redo,还会产生一定量的undo,即使你执行的事务或语句由于某种原因失败了,或者如果你用一条ROLLBACK语句请求回滚,就可以利用这些undo信息将数据回滚到修改之前的样子。
与redo不同的是,redo存放在重做日志文件中,undo存放在数据库内部的某个特殊字段中,这称为undo段,undo段位于共享表空间内。

3.事务控制语句

3.1事务控制语句
(1)start transaction|begin:显示地开启一个事务;

      start transaction、begin语句都可以在MySQL命令下显示地开启一个事务。但是在存储过程中,MySQL分析会自动将begin识别为begin ... end,因此在存储过程中,只能使用start transaction语句来开启一个事务。

(2)commit|commit work:提交事务,并使得已对数据库做的修改称为永久性的;

       commit和commit work语句基本上是一致的,都是用来提交事务。不同之处在于,commit work用来控制事务结束后的行为是chain还是release。可以通过completion_type来进行控制。completion_type的默认值为0,表示没有任何操作,此时commit work与commit功能相同;completion_type为1时,commit work等同于commit and chain,表示马上自动开启一个相同隔离级别的事务;completion_type为2时,commit work等同于commit and release,当事务提交之后会自动断开与服务器的连接。

(3)rollback|rollback work:回滚会结束事务,并撤销正在进行的所有未提交的修改;

        rollback和rollback work语句基本上是一致的,都是用来提交事务。不同之处在于,rollback work用来控制事务结束后的行为是chain还是release。可以通过completion_type来进行控制。completion_type的默认值为0,表示没有任何操作,此时commit work与commit功能相同;completion_type为1时,rollback work等同于rollback and chain,表示马上自动开启一个相同隔离级别的事务;completion_type为2时,rollback work等同于rollback and release,当事务提交之后会自动断开与服务器的连接。

(4)savepoint identifier:savepoint允许在事务中创建一个保存点,一个事务中可以有多个savepoint;
(5)release savepoint identifier:删除一个事务保存点,当没有一个保存点执行这句语句时,会抛出一个异常;
(6)rollback to [savepoint] identifier:这个语句与savepoint 命令一起使用,可以把事务回滚到标记点,而不会回滚到标记点之前的任何工作;
(7)set transaction:设置事务的隔离级别。隔离级别有:read uncommitted,read committed,
repeatable read,serializable。

3.2隐式提交的SQL语句
以下这些SQL语句会产生一个隐式提交操作,即执行完这些语句之后,会有一个隐式的commit操作。
(1)DDL语句:alter database … upgrade data directory name,alter enent,alter procedure,
alter table,alter view;create database,create event,create index,create procedure,
create table,create trigger,create view;drop database,drop event,drop index,drop procedure,
drop table,drop trigger,drop view;rename table,truncate table。
(2)用来隐式地修改MySQL架构的操作:create user,drop user,grant,rename user,revoke,
set password。
(3)管理语句:analyze table,cache index,check table,load index into cache,optimize table,
repair table。
此外,可以通过设置autocommit的值来控制隐式提交,autocommit为1(默认值)时表示隐式提交,autocommit为0表示不会隐式提交。

4.事务的隔离级别

有关隔离级别的相关知识,参考了该博客:理解事务的4种隔离级别
SQL标准定义了四个隔离级别:
(1)read uncommitted
读未提交,就是一个事务可以读取另一个未提交事务的数据。
(2)Read committed
读提交,就是一个事务要等另一个事务提交后才能读取数据。
(3)Repeatable read
重复读,就是在开始读取数据(事务开启)时,不再允许修改(update)操作。InnoDB存储引擎的默认事务隔离级别。
(4)Serializable
序列化,在该级别下,事务串行化顺序执行。

在InnoDB存储引擎中,可以使用一下命令来设置当前会话或者全局的事务隔离级别:
set [global | session] transaction isolation level

{
read uncommitted
|Read committed
|Repeatable read
|Serializable
}

如:set @@tx.isolation='read-committed';

如果想在MySQL数据库启动时就设置事务的默认隔离级别,那就需要修改MySQL的配置文件,在[mysqld]中添加入下行:

  [mysqld]
   transaction-isolation=read-committed

查看当前会话的事务隔离级别,可以使用:

select  @@tx_isolation\G;

查看全局事务隔离级别,可以使用:

select  @@global.tx_isolation\G;

5.分布式事务

有关分布式事务的相关知识,可查看该博客:聊聊分布式事务,再说说解决方案
InnoDB存储引擎支持XA事务,通过XA事务可以来支持分布式事务的实现。分布式事务指的是允许多个独立的事务资源参与一个全局事务中,事务资源通常是关系型数据库,但也可以是其他类型的资源。全局事务要求在其中所有参与的事务要么全部提交,要么都回滚。在使用分布式事务时,InnoDB存储引擎的事务隔离级别必须设置为serializable。
分布式事务由一个或多个资源管理器,一个事务管理器以及一个应用程序组成:
①资源管理器:提供访问事务资源的方法。通常一个数据库就是一个资源管理器。
②事务管理器:协调参与全局事务中的各个事务。需要和参与全局事务中的所有资源管理器进行通信。
③应用程序:定义事务的边界,指定全局事务中的操作。
分布式事务使用两段是提交:
①在第一阶段,所有参与全局事务的节点都开始准备,告诉事务管理器他们准备好提交了。
②在第二阶段,事务管理器告诉资源管理器执行rollback还是commit。如果任何一个节点显示不能提交,则所有的节点都被告知需要回滚。
注:参数innodb_support_xa可以查看是否启用了XA事务支持:

show variables like 'innodb_supprot_xa'\G;

以下是一个分布式事务的例子:一个用户需要从上海转10000元到北京的一个用户上。
片段1
这里写图片描述
这里写图片描述

本博客内容来自《mysql技术内幕Innodb存储引擎》()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值