设为首页 加入收藏

TOP

从阿里规约看Spring事务(一)
2023-07-25 21:28:42 】 浏览:69
Tags:从阿里 Spring 事务

目标:事务失效引发的灾难

如下图(张三--->李四转账)

file

tips

下订单-------订单支付-----减库存(失败)

超卖现象

代码回忆:

//实现类
public class UserServiceImpl implements UserService {
	@Autowired
	private UserMapper userMapper;
	@Resource
	private LogService logService;
    
    
	@Override
	@Transactional
//	@Transactional(rollbackFor = Exception.class)
	public void insert() throws Exception {
		method1_Test();
	}




//模拟转账@Transactional
	private  void  method1_Test() throws Exception {
		System.out.println(">>>>>>>>>>>进入到业务方法");
		User user = new User();
		user.setName("张三");
		userMapper.insertUser(user);//张三扣减500元
		addPayment();//模拟李四增加500元(检查异常)

	}
    
    
   //FileNotFoundException extends IOException
	private void addPayment() throws FileNotFoundException {
		FileInputStream in = new FileInputStream("a.txt");//模拟检查异常


	}
    
}

 ......略

如果说你从从事务方法中抛出的是检查异常(io、sql),那么这个时候,Spring将不能进行事务回滚。

是不是很恐怖呢??

所以说,阿里规定
1、让检查异常也回滚:你就需要在整个方法前加上@Transactional(rollbackFor=Exception.class)

2、让非检查异常不回滚:
需要加入@Transactional(notRollbackFor=RunTimeException.class)

3、不需要事务管理(or 日志丢失)
需要加入@Transactional(propagation=Propagation.NOT_SUPPORTED)

课程目标总结

1、解决事务失效:通过源码学习如何让检查异常也回滚(or 运行异常不回滚);从源码角度深入底层原理

2、解决无需事务控制;查询 or 日志记录;通过传播属性如何控制;底层是如何实现的

3、正常的事务执行流程在源码中是如何实现的

1.1 Spring事务总体介绍

在Spring中,事务有两种实现方式:

  1. 编程式事务管理: 编程式事务管理使用TransactionTemplate可实现更细粒度的事务控制。

  2. 申明式事务管理: 基于Spring AOP实现。

    其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

声明式事务好处:

申明式事务管理不需要入侵代码,通过@Transactional就可以进行事务操作,更快捷而且简单,且大部分业务都可以满足,推荐使用。

管是编程式事务还是申明式事务,最终调用的底层核心代码是一致的

1.1.1 编程式事务实现方式

编程式事务,Spring已经给我们提供好了模板类TransactionTemplate,可以很方便的使用,如下图

file
TransactionTemplate全路径名是:org.springframework.transaction.support.TransactionTemplate。这是spring对事务的模板类

实现的接口

用来执行事务的回调方法,

public interface TransactionOperations {

	@Nullable
	<T> T execute(TransactionCallback<T> action) throws TransactionException;

}

InitializingBean这个是典型的spring bean初始化流程中 ,用来在bean属性加载完毕时执行的方法。

public interface InitializingBean {
 
	void afterPropertiesSet() throws Exception;

}

TransactionTemplate的2个接口的impl方法做了什么?

afterPropertiesSet如下

	//	只是校验了事务管理器不为空
@Override
	public void afterPropertiesSet() {
		if (this.transactionManager == null) {
			throw new IllegalArgumentException("Property 'transactionManager' is required");
		}
	}

execute方法如下

	public <T> T execute(TransactionCallback<T> action) throws TransactionException {
		Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");
 
		if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
			return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
		} 
		else {
			//TODO  创建事务 (与声明事务调用同一个方法)
			TransactionStatus status = this.transactionManager.getTransaction(this);
			T result;
			try {
				// 2.执行业务逻辑,这里就是用户自定义的业务代码。如果是没有返回值的,就是doInTransactionWithoutResult()。
				result = action.doInTransaction(status);
			} catch (RuntimeException | Error ex) {
				// Transactional code threw application exception -> rollback
				// 应用运行时异常/错误异常 -> 回滚,调用AbstractPlatformTransa
首页 上一页 1 2 3 4 5 6 下一页 尾页 1/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇一天吃透Redis面试八股文 下一篇.MD语法入门,教你写好readme文档

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目