博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring中的事务
阅读量:7211 次
发布时间:2019-06-29

本文共 5986 字,大约阅读时间需要 19 分钟。

hot3.png

1)spring的事务管理器:

package org.springframework.transaction;public interface PlatformTransactionManager {	TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;	void commit(TransactionStatus status) throws TransactionException;	void rollback(TransactionStatus status) throws TransactionException;}

2)spring的事务定义类:

package org.springframework.transaction;import java.sql.Connection;public interface TransactionDefinition {	// 事务的传播行为	int PROPAGATION_REQUIRED = 0;		// 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。												int PROPAGATION_SUPPORTS = 1;		// 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。	int PROPAGATION_MANDATORY = 2;		// 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。	int PROPAGATION_REQUIRES_NEW = 3;	// 创建一个新的事务,如果当前存在事务,则把当前事务挂起。	int PROPAGATION_NOT_SUPPORTED = 4;	// 以非事务方式运行,如果当前存在事务,则把当前事务挂起。	int PROPAGATION_NEVER = 5;			// 以非事务方式运行,如果当前存在事务,则抛出异常。	int PROPAGATION_NESTED = 6;			// 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则等价于PROPAGATION_REQUIRED。		// 事务的隔离级别	int ISOLATION_DEFAULT = -1;			// 使用底层数据库的默认隔离级别。	int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;	int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;	int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;	int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;	/**	 * Use the default timeout of the underlying transaction system, or none if timeouts are not supported.	 */	// 事务超时:指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。	// 默认为底层事务系统的超时值,如果底层数据库事务系统没有设置超时值,那么就是none,没有超时限制。	int TIMEOUT_DEFAULT = -1;	int getPropagationBehavior();	int getIsolationLevel();	int getTimeout();	boolean isReadOnly();	String getName();}

3)spring中事务的回滚:

1)spring推荐以抛出异常的方式来回滚一个事务。2)spring事务管理器会捕捉任何未处理的异常,然后根据相应的配置来判断是否回滚抛出异常的事务。	1>默认配置下,spring只有在抛出的异常为运行时unchecked异常时才回滚该事务,也就是抛出的异常为RuntimeException的子类(Errors也会导致事务回滚),而抛出checked异常则不会导致事务回滚。	2>可以配置在抛出哪些异常时回滚事务,包括checked异常;也可以明确设置哪些异常抛出时不回滚事务。

4)@Transactional注解

属性					类型							描述value					String				可选的限定描述符,指定使用的事务管理器propagation				enum 				可选的事务传播行为设置isolation				enum 				可选的事务隔离级别设置readOnly				boolean				读写或只读事务,默认读写timeout					int 				(in seconds granularity)事务超时时间设置rollbackFor				(继承Throwable的)Class数组		导致事务回滚的异常类数组rollbackForClassName	(继承Throwable的)类名数组		导致事务回滚的异常类名字数组noRollbackFor			(继承Throwable的)Class数组		不会导致事务回滚的异常类数组noRollbackForClassName	(继承Throwable的)类名数组		不会导致事务回滚的异常类名字数组用法:可以写在类(接口)上,也可以方法上。	1)当作用于类上时,该类的所有public方法将都具有该类型的事务属性。	2)可以在方法上使用该注解来覆盖类级别上的设置。	3)Spring建议不要在接口或接口方法上使用该注解,因为只有在使用基于接口的代理时它才会生效。	4)在private、protected、default的方法上使用该注解,则该注解将被忽略,也不会抛出任何异常。	5)默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是说:类内部方法调用本类内部的其它方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰!

5)原理:

1)spring的事务管理是通过spring的AOP(动态代理)来实现的。	spring中事务生效的一个前提:调用的方法必须被TransactionInterceptor拦截。		说明:只有通过TransactionInterceptor拦截的方法才会被加入到spring的事务管理中。		举例:			在方法A中调用@Transactional修饰的方法B时,如果方法A与方法B在同一个类TestClass中,则加在方法B上的@Transactional注解不起作用,因为此时方法A对方法B的调用是不会被拦截器拦截的!			解决办法:在方法A中,使用当前的代理对象来调用方法B。eg:((TestClass)AopContext.currentProxy()).B();2)对于正常的事务管理,必须关闭数据库的自动提交模式,spring会将底层连接的自动提交特性设置为false。	package org.springframework.jdbc.datasource;	public class DataSourceTransactionManager extends AbstractPlatformTransactionManager implements ResourceTransactionManager, InitializingBean {		private DataSource dataSource;		/**		 * This implementation sets the isolation level but ignores the timeout.		 */		[@Override](https://my.oschina.net/u/1162528)		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); // 【spring将底层连接的自动提交设置为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) {				DataSourceUtils.releaseConnection(con, this.dataSource);				throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);			}		}	}

6)配置文件:

1)注解的形式:	spring + mybatis:		说明:mybatis会自动参与到spring事务的管理中,无需额外配置,只要org.mybatis.spring.SqlSessionFactoryBean引用的数据源与DataSourceTransactionManager引用的数据源一致即可,否则事务管理不起作用。			
spring + hibernate:
2)切面的形式:

转载于:https://my.oschina.net/u/1399755/blog/1499906

你可能感兴趣的文章
基于DNS实现智能化访问网站
查看>>
单主机Docker容器VLAN划分
查看>>
利用SVN的post-commit钩子实现多项目自动同步
查看>>
Jmeter3.1官方自带的HTML图形测试报告 + 汉化
查看>>
文件共享存储&&主备实时热备实现方案
查看>>
一文看懂迁移学习:怎样用预训练模型搞定深度学习?
查看>>
Elasticsearch 5.3 集群搭建
查看>>
linux基础命令练习1
查看>>
【MySQL】【高可用】从masterha_master_switch工具简单分析MHA的切换逻辑
查看>>
xargs 和 exec详解
查看>>
ipmi对于统一硬件管理的意义
查看>>
SQL数据库高级查询命令(3)
查看>>
Ansible-playbook 拾遗
查看>>
以DES的方式实现对称加密,并提供密钥
查看>>
latex/Xelatex书籍排版总结---顺便附上一本排好的6寸android书…
查看>>
shell变量定义
查看>>
SSH远程登录VWware上的LFS
查看>>
互联生活:业务模式聚焦
查看>>
ELK采集之nginx 日志高德地图出城市IP分布图
查看>>
epson me 1+只有主机能打印不能共享网络打印问题的处理
查看>>