栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【HBZ分享】spring事务的原理,及隔离级别,及传播机制,及失效场景

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【HBZ分享】spring事务的原理,及隔离级别,及传播机制,及失效场景

模拟Spring事务,手写功能类似@Transaction的代码gitee地址

手写事务地址: https://gitee.com/huang_bao_se/hbz-transaction

Spring事务类型
  1. 编程式事务:手动的去begin, commit, rollback这些操作,叫编程事务,代码会产生冗余,一大堆事务代码,但编程式事务并不是一无是处,他更灵活,某些情况还必须要使用编程事务。但如果编程式事务没用好,容易把数据锁住,即没执行【提交】或【回滚】
  2. 声明式事务:在方法上加上事务的注解@Transaction,这就是声明式事务
  3. 声明式事务提交时机:当方法执行完毕 并 没有【抛出异常】则就会提交吗,注意:抛出异常和出现异常时两回事,如果异常被捕获了,则依然不会回滚,底层是AOP的机制,自行用try…catch捕获,底层AOP是无法感知的,即也不会回滚,如果要写catch,则catch一定要加上如下代码
try{
	...
}catch(Exception e){
	// 手动回滚,AOP将事务缓存到了当前线程,所以直接根据当前线程获取该事务对象,回滚即可
	TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
	
	// 或者直接抛出异常(不推荐,如果在catch还要抛异常,则也没有必要加try..catch了)
	// throw new Exception();
}
  1. spring事务的默认传播机制:事务传播机制主要应用于A方法中调用B方法。spring默认的事务传播机制是A方法加了事务,则B方法会延用A方法的事务,如果A方法没有事务,则B方法会自行创建一个事务
  2. spring事务的默认隔离级别:spring事务的隔离了级别默认和Mysql一致,而Mysql的事务隔离级别是可重复读,所以spring的隔离级别也是可重复读。
  3. spring事务隔离级别比mysql多一个,多这一个就是与mysql 隔离机制相同这个级别,即mysql 如果更改了隔离级别,spring也会跟着更改,其余4个隔离级别和MySQL完全一致–>请看后面【spring事务隔离级别】

编程式事务的源码:

// 事务类
public class TestTransaction{

	@Autowired
	private DataSourceTransactionManager dataSourceTransactionManager;
	
	// 开启事务,并配置默认的事务传播机制
	public TransactionStatus begin(){
		TransactionStatus transaction = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
		return transaction;
	}
	
	// 提交事务
	public void commit(TransactionStatus transactionStatus){
		dataSourceTransactionManager.commit(transactionStatus);
	}
	
	// 回滚事务
	public void rollback(TransactionStatus transactionStatus){
		dataSourceTransactionManager.rollback(transactionStatus);
	}
}


// 测试方法
public static void main(String arg[]){
	TestTransaction testTransaction = new TestTransaction();
	
	// 开启事务
	TransactionStatus transaction = testTransaction .begin();
	try{
		// 执行sql
		sql.updateDate(obj);
		// 提交事务
		testTransaction.commit(transaction );
		
	}catch(Exception e){
		// 回滚事务
		testTransaction .rollback(transaction )
	}	

}
Spring事务隔离级别
  1. ISOLATION_DEFAULT(spring事务的默认隔离级别):使用后端数据库默认的隔离级别。后端数据库是什么他就是什么隔离级别,后端数据库用【未提交读】,那spring也用未提交读。如果选可重复读,那即使数据库的级别是未提交读,那spring的事务也会是可重复读

  2. ISOLATION_READ_UNCOMMITTED:未提交读

  3. ISOLATION_READ_COMMITTED: 提交读

  4. ISOLATION_REPEATABLE_READ: 不可重复读

  5. ISOLATION_SERIALIZABLE:串行化

Spring事务传播机制
  1. REQUIRED(required默认属性)
    如果A方法调用B方法,B方法需要事务,则如果A方法已经创建了事务,则B方法不会再创建事务,会支持A方法的事务,如果当前没有事务,才会重新创建一个新事物
  2. MANDATOR(mandator)
    仅支持当前事务,如果当前没有事务,就会抛异常。如果A没创建事务,那么B还需要,那就会抛异常
  3. NEVER(never)
    不能存在事务,如果当前有事务,会抛出异常,A方法创建了事务,B方法就会抛异常,因为是NEVER不允许有事务。
  4. REQUIRES_NEW(requires_new)
    新建事务。如果当前存在事务,则当前事务挂起。即如果A创建了事务,B依然会创建事务,并且会挂起A的事务
  5. SUPPORTS(supports)
    支持当前事务,如果当前没有事务,也不会创建事务,就直接执行了。即A方法创建了事务,B方法会使用这个事务。A没有创建事务,B就进行无事务操作,总之B不会创建新事物
Spring事务失效场景
  1. 访问权限不是public
  2. 加了final修饰,此时该方法不可被子类重写
  3. 方法内部调用,即A方法调用本类中B方法,事务加在B方法上,此时不生效,因为spring事务就是一个切面,通过动态代理对象进行事务,同方法调用是通过this,并不是动态代理类
  4. 自己类注入了自己对象,即A类中注入A类的对象,再通过A类对象调用带有事务的方法,此时不生效
  5. 未被spring管理,没有加到springIOC容器
  6. 多线程调用中
  7. 表本身不支持事务,比如使用了MyISAM
  8. 未开启事务
  9. 被try…catch捕捉了,而且还没手动抛异常
  10. spring的传播属性写错了,比如用了NEVER这种,根部就不让存在事务,那事务必然失效。默认是REQUIRED,是可以存在事务的。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1013563.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号