spring事务原理剖析
来源:互联网 发布:光明数据 东华 编辑:程序博客网 时间:2024/06/05 04:08
spring 事务基本原理
先看看Java JDBC操作数据库的基本步骤
获取数据库连接 DriverManager.getConnection
开启事务conn.setAutoCommit()
执行CRUD
提交事务|回滚事务conn.commit() / conn.rollback()
关闭连接 conn.close()
spring事务提供了编程式
和声明式
两种方式。使用spring事务,可以不再写2、4步骤代码,spring事务代理会帮我们自动完成事务开启、正常提交事务or异常回滚事务操作。
这里顺便提下我在学些过程中踩到的坑,MySQL数据库事务回滚对innodb索引有效, 而myisam是不支持事务的, 建表的时候选好索引类型。
spring 事务原理底层离不开数据库事务的支持。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。
spring 事务核心概念
Spring 事务的两大核心 :传播 + 隔离
1.事务传播
多个可以回滚的保存点
。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。2. 事务隔离
本质就是数据库隔离级别
spring定义的五种事务隔离级别(本质是4种事务,1种是默认事务,其余四种和数据库的4种事务一一对应)
注意:隔离级别越高,越能保证数据一致性,但这是要付出性能代价的。使用事务的时候谨慎选取事务隔离级别。
深入spring 事务原理
事务源码分析:
核心四大类
1) PlatformTransactionManager : spring 事务核心基础接口。主要实现常见有:
- DataSourceTransactionManager : 适用于使用JDBC和iBatis进行数据持久化操作的情况
- HibernateTransactionManager :适用于使用Hibernate进行数据持久化操作的情况。
- JtaTransactionManager:适用于使用JPA进行数据持久化操作的情况。
常用接口:
Public interface PlatformTransactionManager{ - TransactionStatus getTransaction(TransactionDefinition definition) - void commit(TransactionStatus status) - void rollback(TransactionStatus status)}
2) TransactionDefinition : 定义了事务隔离、传播等属性
事务隔离级别: 隔离级别是指若干个并发的事务之间的隔离程度。TransactionDefinition 接口中定义了五个表示隔离级别的常量:(有一个默认常量,其实也就是四种隔离级别)
3)TransactionStatus :接口提供了一个简单的控制事务执行和查询事务状态的方法。
public interface TransactionStatus{ boolean isNewTransaction(); void setRollbackOnly(); boolean isRollbackOnly();}
4)TransactionTemplate
- xml config
<!-- 事物处理器配置 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="应用DBsource"/> </bean> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="transactionManager" /> </bean>
- spring 编程式事务使用入口
transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { // todo 这里是业务逻辑code } });
TransactionTemplate.execute源码分析:
获取TransactionStatus对象, 通过action.doInTransaction(status)回调包裹在事务中的业务逻辑. 如果业务正常, 则提交事务。否则事务异常, 调用rollbackOnException进行回滚, 继续跟进rollbackOnException方法, 底层是通过 conn.rollback() 来回滚的。
@Override public <T> T execute(TransactionCallback<T> action) throws TransactionException { if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) { return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action); } else { // 获取事务(底层封装了DataSource、connection) TransactionStatus status = this.transactionManager.getTransaction(this); T result; try { // action 回调业务逻辑代码 result = action.doInTransaction(status); } catch (RuntimeException ex) { // Transactional code threw application exception -> rollback rollbackOnException(status, ex); throw ex; } catch (Error err) { // Transactional code threw error -> rollback rollbackOnException(status, err); throw err; } catch (Exception ex) { // Transactional code threw unexpected exception -> rollback rollbackOnException(status, ex); throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception"); } this.transactionManager.commit(status); return result; } }
getTransaction 方法负责准备事务开启前期等工作。有个比较重要的doBegin方法
把事务自动提交关闭、设置自动超时等
@Override protected void doBegin(Object transaction, TransactionDefinition definition) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction; Connection con = null; try { if (txObject.getConnectionHolder() == null || txObject.getConnectionHolder().isSynchronizedWithTransaction()) { Connection newCon = this.dataSource.getConnection(); if (logger.isDebugEnabled()) { logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction"); } txObject.setConnectionHolder(new ConnectionHolder(newCon), true); } txObject.getConnectionHolder().setSynchronizedWithTransaction(true); con = txObject.getConnectionHolder().getConnection(); Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition); txObject.setPreviousIsolationLevel(previousIsolationLevel); // Switch to manual commit if necessary. This is very expensive in some JDBC drivers, // so we don't want to do it unnecessarily (for example if we've explicitly // configured the connection pool to set it already). if (con.getAutoCommit()) { txObject.setMustRestoreAutoCommit(true); if (logger.isDebugEnabled()) { logger.debug("Switching JDBC Connection [" + con + "] to manual commit"); } con.setAutoCommit(false); } txObject.getConnectionHolder().setTransactionActive(true); int timeout = determineTimeout(definition); if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { txObject.getConnectionHolder().setTimeoutInSeconds(timeout); } // Bind the session holder to the thread. if (txObject.isNewConnectionHolder()) { TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder()); } } catch (Throwable ex) { if (txObject.isNewConnectionHolder()) { DataSourceUtils.releaseConnection(con, this.dataSource); txObject.setConnectionHolder(null, false); } throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex); } }
- spring事务原理剖析
- 分布式事务底层原理剖析
- 【总结】Spring原理剖析
- Spring原理剖析
- Spring深入浅出原理剖析
- 【总结】Spring原理剖析
- Spring原理剖析
- Spring事务原理
- Spring事务原理
- Spring事务原理
- Spring事务原理
- Spring 事务代理原理
- Spring事务原理
- spring事务原理二
- spring--事务原理
- Spring事务原理
- Spring事务原理
- spring事务原理
- 【JSOUP】如何解析HTML对象?学习笔记1
- docker总结二——命令
- docker总结三
- 【LeetCode】292 Nim Game
- Python基础--数值类型
- spring事务原理剖析
- docker总结四
- Python发送短信
- docker总结五
- openlayers3 ol3热力图 json
- 见习小感想
- Windows10自带应用的卸载和恢复
- Docker Toolbox创建虚拟机时 --virtualbox-share-folder 共享目录参数的正确用法
- Frame 窗口