事务特性 #
现实世界中的业务场景需要映射到数据库世界。显示世界中的一次状态转换需要满足下面几个特性(事务特性):
- 原子性。
- 隔离性。
- 一致性。
- 持久性。
原子性 #
一个事务中可能包含多个操作/步骤,这些操作要么全部做,要么全部不做。 如果在执行过程中发生了错误,要把已经执行的操作恢复成没有操作之前的样子。
隔离性 #
多个事务之间不会相互影响。
一致性 #
数据库只是现实世界的一个映射,现实中存在的约束要在数据库中有所体现。如果数据库中的数据全部符合现实世界中的约束,我们就说这些数据是一致的。
数据库的一致性是指数据库中的数据应该符合相关规则和约束。
为了保证数据库中数据的一致性,需要两方面的努力:
数据库本身的约束 #
数据库本身能解决一部分一致性需求。可以通过为表建立主键、唯一索引等来进行约束,满足部分一致性需求。
业务代码的约束 #
更多的一致性需求需要靠写业务代码的程序员自己保证。
持久性 #
事务完成后,事务中的数据库操作所修改的数据都应该在磁盘中保留下来。
事务概念 #
事务是一个抽象的概念,对应着一个或多个数据库操作。 根据这些操作所执行的不同阶段,把事务划分为不同的状态:
- 活动的。事务对应的操作正在进行中。
- 部分提交的。事务对应的操作已经完成,但是还没有刷盘。
- 失败的。处于活动的或部分提交的事务,可能遇到某些错误而无法继续执行,这时候事务就处于失败的状态。
- 中止的。进行回滚,把数据库恢复到事务开始之前的状态,这时候事务就处于中止的状态。
- 提交的。处于部分提交的事务将修改过的数据都刷新到磁盘中。
只有当事务处于提交的或者中止的状态时,事务才算结束。
事务语法 #
开启事务 #
可以通过begin和start transaction来开启一个事务。两者具有相同的功效,都标志着开启一个事务。
相较于begin,start transaction后面可以添加修饰符。
- READ ONLY。标识当前事务是一个只读事务。
只读事务只是不允许修改那些其他事务也能访问的表中的数据,但可以对临时表进行修改。
- READ WRITE。标识当前事务是一个读写事务。默认就是读写事务。
- WITH CONSISTENT SNAPSHOT。启动一致性读。
提交与回滚 #
提交事务:commit。 回滚事务:rollback。
rollback是程序员手动回滚事务时使用。如果事务在执行过程中发生某些错误,事务会自动回滚。比如发生死锁时,会回滚事务。
支持事务的存储引擎 #
MySQL中,目前只有InnoDB和NDB支持事务。
自动提交 #
事务默认自动提交。可以通过查看变量autocommit的值来查看是否开启了自动提交。
show variables like 'autocommit';
默认情况下,是开启自动提交的,每一条语句都算是一个独立事务。
可以关闭自动提交:
- 显式使用begin或start transaction开启事务。
- 使用set autocommit=OFF 关闭自动提交。
隐式提交 #
隐式提交是指在显式开启事务或关闭自动提交时,如果输入了某些语句,会自动触发提交(和手动commit类似)。 这些语句包括:
- DDL语句。
- 使用或修改mysql数据库中的表。
- 事务控制或锁定的语句。如在事务未提交时,再次执行begin,会自动提交之前的事务。
- 加载数据的语句。
- 关于复制的语句。
- 其它语句。
保存点 #
保存点是指在事务中,可以设置一个保存点,当事务回滚时,可以回滚到哪个店。