购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

4.6 简单事务管理

MySQL的InnoDB存储引擎支持事务管理。所谓的事务就是一个或多个SQL语句中涉及的多项操作作为一个执行单元,要么全部成功,要么全部失败。事务具有4个特性,简称ACID特性。

1.原子性(Atomicity)

原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须完全应用到数据库,如果操作失败则不能对数据库有任何影响。

2.一致性(Consistency)

一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说,一个事务执行之前和执行之后都必须处于一致性状态。举例来说,假设用户A和用户B两者的钱加起来一共是1000元,那么不管A和B之间如何转账、转几次账,事务结束后两个用户的钱相加起来应该还是1000元,这就是事务的一致性。

3.隔离性(Isolation)

隔离性是当多个用户并发访问数据库时,如同时操作同一张表时,数据库为每个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。关于事务的隔离性,MySQL数据库提供了4个隔离级别:read uncommitted(读未提交)、read committed(读已提交)、repeatable read(可重复读)和serializable(串行化)。MySQL默认隔离级别为repeatable read,并采用MVCC多版本控制技术避免数据库的脏读、不可重复读和幻读问题。本节只是讨论事务的简单处理操作,关于高级事务管理和锁机制的问题请关注本书的姊妹篇《剑指MySQL——架构、调优与运维》。

4.持久性(Durability)

持久性是指一个事务一旦被提交了,那么对数据库中数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

4.6.1 事务控制

在默认情况下,MySQL是自动提交(autocommit)的,即如果SQL执行成功了,就直接自动生效了。如果需要手动提交和回滚事务,就需要通过明确的事务控制命令来开始事务,这是和Oracle等其他数据库的事务管理明显不同的地方。

如果只需要对某些语句进行事务控制,则使用“START TRANSACTION”语句开始一个事务比较方便,这样事务结束后可以回到自动提交的方式。当使用“START TRANSACTION”语句开始一个事务后,执行相应的SQL语句,需要执行ROLLBACK回滚语句或COMMIT提交语句结束事务。开始事务和结束事务的SQL语法格式如下。

如果希望所有的事务都不是自动提交的,那么通过修改AUTOCOMMIT来控制事务比较方便,这样就不用在每个事务开始的时候执行“START TRANSACTION”语句。

如果设置了“SET AUTOCOMMIT=0”,那么所有INSERT、UPDATE、DELETE等支持事务的SQL语句都需要通过明确的命令进行提交或回滚,否则这些SQL语句就不会生效。“SET AUTOCOMMIT”语句只对当前连接会话有效。

例如,添加一条记录到“tb_student”表,之后回滚,在事务控制演示之前,先使用SELECT语句查看“tb_student”表的当前数据。

下面开启事务,并演示添加记录之后回滚的效果。

(1)开始事务。

(2)添加一条记录到“tb_student”表。

(3)使用SELECT语句查看“tb_student”表的当前数据。

从结果中可以看出,添加记录成功。

(4)回滚结束事务。

(5)再次使用SELECT语句查看“tb_student”表的当前数据。

从结果中可以看出,刚刚添加的记录又回滚了,即撤销了。

例如,添加一条记录到“tb_student”表,之后提交。

(1)开始事务。

(2)添加一条记录到“tb_student”表。

(3)使用SELECT语句查看“tb_student”表的当前数据。

从结果中可以看出,添加记录成功。

(4)提交结束事务。

(5)再次使用SELECT语句查看“tb_student”表的当前数据。

从结果中可以看出,添加记录成功。就算我们退出当前客户端连接,再重新登录连接,该记录也仍然存在,即一旦提交就表示永久生效了。

4.6.2 回滚部分事务

在事务中可以通过定义SAVEPOINT(保存点),指定回滚事务的一个部分,但是不能指定提交事务的一个部分。对于复杂的SQL操作,可以定义多个不同的SAVEPOINT,当满足不同的情况时,可回滚不同的SAVEPOINT。需要注意的是,如果定义了相同名字的SAVEPOINT,则后面的SAVEPOINT会覆盖之前的定义。对于不再需要的SAVEPOINT,可以通过“RELEASE SAVEPOINT”命令删除SAVEPOINT,删除后的SAVEPOINT就不能再使用了。

例如,对“tb_student”表进行INSERT、UPDATE、DELETE操作,并定义多个SAVEPOINT,来演示回滚事务的一个部分。先使用SELECT语句查看“tb_student”表的当前数据。

下面开启事务,并演示在INSERT、UPDATE和DELETE操作后分别定义SAVEPOINT,之后回滚部分事务的效果。

(1)开始事务。

(2)添加一条记录到“tb_student”表。

(3)使用SELECT语句查看“tb_student”表的当前数据。

查询结果表明添加成功。

(4)定义第一个SAVEPOINT,SAVEPOINT的名字为“insertpoint”。

(5)修改“tb_student”表中“sname”字段为“张三”的“math”和“english”字段值为“100”。

(6)使用SELECT语句查看“tb_student”表的当前数据。

查询结果表明修改成功。

(7)定义第二个SAVEPOINT,SAVEPOINT的名字为“updatepoint”。

(8)删除“tb_student”表中“sid”字段为“5”的记录。

(9)使用SELECT语句查看“tb_student”表的当前数据。

查询结果表明删除成功。

(10)回滚到名字为“insertpoint”的SAVEPOINT。

(11)使用SELECT语句查看“tb_student”表的当前数据。

从结果中可以看出,名字为“insertpoint”的SAVEPOINT之前的INSERT操作结果没有被回滚,名字为“insertpoint”的SAVEPOINT之后的UPDATE和DELETE操作被回滚了。

4.6.3 DDL语句不支持回滚

另外,需要说明的是,所有的DDL语句是不能回滚的,并且部分DDL语句会造成隐式的提交,这一点和Oracle的事务管理相同。MySQL的基础事务管理操作主要是针对插入(INSERT)、修改(UPDATE)、删除(DELETE)等DML语句操作。

例如,DELETE和TRUNCATE语句的区别演示。SQL语句示例如下。

(1)演示使用DELETE语句删除记录并回滚成功。

从上面的结果可以看出,DELETE语句支持事务回滚。

(2)演示使用TRUNCATE语句删除记录并回滚失败。

从上面的结果可以看出,TRUNCATE语句不支持事务回滚。 Lk1MzhXAAKhgrGNvQtUqF08qggU74kOHWKDbOF9bywti5W6JUtTcNfFjAxn5fQ7u

点击中间区域
呼出菜单
上一章
目录
下一章
×