事务主要分为五大类,分别为扁平事务、带有保存点的扁平事务、链式事务、嵌套事务和分布式事务。本节就简单介绍一下事务的五大类型。
扁平事务是事务操作中最常见,也是最简单的事务。在数据库中,扁平事务通常由begin或者start transaction字段开始,由commit或者rollback字段结束。在这之间的所有操作要么全部执行成功,要么全部执行失败(回滚)。当今主流的数据库都支持扁平事务。
扁平事务虽然是最常见、最简单的事务,但是无法提交或者回滚整个事务中的部分事务,只能把整个事务全部提交或者回滚。为了解决这个问题,带有保存点的扁平事务出现了。
通俗地讲,内部设置了保存点的扁平事务,就是带有保存点的扁平事务。带有保存点的扁平事务通过在事务内部的某个位置设置保存点(savepoint),达到将当前事务回滚到此位置的目的,示例如下。
在MySQL数据库中,通过如下命令设置事务的保存点。
savepoint [savepoint_name]
例如,设置一个名称为save_user_point的保存点,代码如下所示。
savepoint save_user_point;
通过如下命令将当前事务回滚到定义的保存点位置。
rollback to [savepoint_name]
例如,将当前事务回滚到定义的名称为save_user_point的保存点位置,代码如下所示。
rollback to save_user_point;
通过如下命令删除保存点。
release savepoint [savepoint_name]
例如,删除当前事务中名称为save_user_point的保存点,代码如下所示。
release savepoint save_user_point;
从本质上讲,普通的扁平事务也是有保存点的,只是普通的扁平事务只有一个隐式的保存点,并且这个隐式的保存点会在事务启动的时候,自动设置为当前事务的开始位置。也就是说,普通的扁平事务具有保存点,而且默认是事务的开始位置。
链式事务是在带有保存点的扁平事务的基础上,自动将当前事务的上下文隐式地传递给下一个事务。也就是说,一个事务的提交操作和下一个事务的开始操作具备原子性,上一个事务的处理结果对下一个事务是可见的,事务与事务之间就像链条一样传递下去。
注意
链式事务在提交的时候,会释放要提交的事务中的所有锁和保存点,也就是说,链式事务的回滚操作只能回滚到当前所在事务的保存点,而不能回滚到已提交事务的保存点。
顾名思义,嵌套事务就是有多个事务处于嵌套状态,共同完成一项任务的处理,整个任务具备原子性。嵌套事务最外层有一个顶层事务,这个顶层事务控制着所有的内部子事务,内部子事务提交完成后,整体事务并不会提交,只有最外层的顶层事务提交完成后,整体事务才算提交完成。
关于嵌套事务需要注意以下几点。
1)回滚嵌套事务内部的子事务时,会将事务回滚到外部顶层事务的开始位置。
2)嵌套事务的提交是从内部的子事务向外依次进行的,直到最外层的顶层事务提交完成。
3)回滚嵌套事务最外层的顶层事务时,会回滚嵌套事务包含的所有事务,包括已提交的内部子事务。
在主流的关系型数据库中,MySQL不支持原生的嵌套事务,而SQL Server支持。这里,笔者不建议使用嵌套事务。
分布式事务指的是事务的参与者、事务所在的服务器、涉及的资源服务器以及事务管理器等分别位于不同分布式系统的不同服务或数据库节点上。简单来说,分布式事务就是一个在不同环境(比如不同的数据库、不同的服务器)下运行的整体事务。这个整体事务包含一个或者多个分支事务,并且整体事务中的所有分支事务要么全部提交成功,要么全部提交失败。
例如,在电商系统的下单减库存业务中,订单业务所在的数据库为事务A的节点,库存业务所在的数据库为事务B的节点。事务A和事务B组成了一个具备ACID特性的分布式事务,要么全部提交成功,要么全部提交失败。