你真的了解Spring的嵌套事务与JDBC的savePoint机
2023-07-06 本文已影响0人
CoderInsight
嵌套事务
嵌套事务是指一个事务内部包含了另一个或多个子事务的概念。在嵌套事务中,外部事务被称为父事务,内部事务被称为子事务。父事务可以包含多个子事务,并且父事务和子事务之间存在层级关系。
- 不同层级的事务注解:父事务和子事务使用不同的事务传播属性时,可能会导致事务失效。如果父事务的传播属性为 REQUIRED,而子事务的传播属性为 REQUIRES_NEW,那么子事务将独立于父事务,并且父事务的回滚不会影响子事务。
- 外部方法调用:如果嵌套事务中的子事务是通过外部方法调用的,而外部方法没有事务注解,那么子事务将独立于父事务,在外部方法调用结束后才提交或回滚子事务。这种情况下,嵌套事务的特性可能无法生效。
注意:如果采用ShardingSphere(4.0.0-RC1与5.0.x
)作为数据源实现分库分表或者读写分离,那么注意其是不直接支持的嵌套事务的,即程序会抛出如下异常:
org.springframework.transaction.CannotCreateTransactionException: Could not create JDBC savepoint; nested exception is java.sql.SQLFeatureNotSupportedException: setSavepoint name
at org.springframework.jdbc.datasource.JdbcTransactionObjectSupport.createSavepoint(JdbcTransactionObjectSupport.java:122)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.sql.SQLFeatureNotSupportedException: setSavepoint name
at org.apache.shardingsphere.shardingjdbc.jdbc.unsupported.AbstractUnsupportedOperationConnection.setSavepoint(AbstractUnsupportedOperationConnection.java:71)
at org.springframework.jdbc.datasource.ConnectionHolder.createSavepoint(ConnectionHolder.java:184)
at org.springframework.jdbc.datasource.JdbcTransactionObjectSupport.createSavepoint(JdbcTransactionObjectSupport.java:119)
... 104 common frames omitted
1),补充Spring的嵌套事务的实现原理(savepoint机制)
补充:嵌套事务的核心实现原理是依赖JDBC的 savepoint
机制,因为嵌套事务是在一个事务中启动另一个子事务,在Springboot中,Spring会使用JDBC来创建一个事务,并将其关联到当前线程中,当方法执行到嵌套事务的点时,Spring会使用JDBC的SavePoint
机制来创建一个保存点(savePoint
),并将其记录在当前事务的状态中。实际上,在嵌套事务中每一个事务都有自己的保存点,如果子事务失败或者回滚,它可以回滚到自己的保存点,而不会影响其他的事务。
- 默认情况下,我们创建了一个数据的连接,会运行在自动提交模式下,这意味着,任何时候我们执行了一条SQL之后,事务就会自动提交,基于事务的持久性,当一个事务提交后,数据会被持久化到数据库中。那么如果我们想让一组SQL语句成为事务的一部分,那么我们就可以选择让所有的语句在运行成功的时候再提交,并且如果出现任何异常,这些语句作为事务的一部分,其是可以全部回滚的。
- 有时候一个事务可能是一组复杂的语句,因为可能想要回滚到事务中某一个特殊的点,便可以通过
JDBC Savepoint
帮助我们创建保存点(savepoint
),这样就可以回滚到指定的点。当事务提交或者整个事务回滚之后,为事务创建的的任何保存点都会释放并变为无效。同时把事务回滚到一个保存点,会使其他所有的保存点自动释放为无效。 - 应用场景:我们可以使用两个事务,当数据成功的保存数据,使用另外的一个事务管理插入日志的操作,这样可以保证即时在业务失败的情况下不会影响日志的保存。
2),补充savepoint(保存点)与CheckPoint(检查点)的区分
- 在Spring事务中,savePoint(保存点)是用于支持嵌套事务的机制之一。它允许在一个事务中创建多个事务,并为每一个子事务设置一个保存点,每一个保存点代表子事务的某个执行点,如果子事务失败或者回滚了,可以将事务回滚到对应的保存点,而不影响其他的子事务。
- 在数据库事务中,checkPoint(检查点)是指将当前数据库的状态保存到磁盘的某个时间点。它用于恢复数据库,以确保在故障或错误时可以回滚到某一个一致性的状态。CheckPoint通常是由数据库管理系统自动触发的,并且与事务的嵌套无直接关系。
-
二者对比:Savepoint在Spring中是通过JDBC的
Connection
对象提供的,可以使用setSavepoint()
创建保存点,使用rollback(Savepoint)
回滚到保存点。因此,Savepoint和CheckPoint是两个不同的概念,Savepoint用于支持嵌套事务,在Spring及其所使用的JDBC连接上进行管理。而CheckPoint在数据库层面用于持久化数据库的一致状态。