Spring 的事务实现原理和传播机制

Spring 为事务管理提供了丰富的功能支持。Spring 事务管理分为编程式和声明式两种。编程式事务指的是通过编码方式实现事务;声明式事务基于 AOP,将具体的逻辑与事务处理解耦。生命式事务管理使业务代码逻辑不受污染,因此实际使用中声明式事务用的比较多。

声明式事务有两种方式,一种是在配置文件(XML)中做相关的事务规则声明,另一种是基于 @Transactional 注解的方式。本文着重介绍基于 @Transactional 注解的事务管理。

需要明确几点:

默认配置下 Spring 只会回滚运行时、未检查异常(继承自 RuntimeException 的异常)或者 Error。@Transactional 注解只能应用到 public 方法才有效。

Spring 官方文档:docs.spring.io/spring/docs…

图片.png

在默认的代理模式下,只有目标方法由外部调用,才能被 Spring 的事务拦截器拦截。在同一个类中的两个方法直接调用,是不会被 Spring 的事务拦截器拦截,就像上面的 save 方法直接调用了同一个类中的 method1方法,method1 方法不会被 Spring 的事务拦截器拦截。可以使用 AspectJ 取代 Spring AOP 代理来解决这个问题,但是这里暂不讨论。

为了解决这个问题,我们可以新建一个类。

1
2
3
4
5
6
7
8
9
10
11
12
13
java复制代码@Service
public class OtherServiceImpl implements OtherService {

@Autowired
private UserMapper userMapper;

@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public void method1() {
User user = new User("李四");
userMapper.insertSelective(user);
}
}

然后在 save 方法中调用 otherService.method1 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
java复制代码@Autowired
private OtherService otherService;

@Transactional(propagation = Propagation.REQUIRED)
@Override
public void save() {

otherService.method1();

User user = new User("zhangsan");
userMapper.insertSelective(user);

if (true) {
throw new RuntimeException("save 抛异常了");
}
}

这下,otherService.method1 方法的数据插入成功,save 方法的数据未插入,事务回滚。

参考链接:
blog.csdn.net/NathanniuBe…
zhuanlan.zhihu.com/p/157646604

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%