Spring事务

事务:一组操作的集合

事务是怎么实现的

底层基于数据库事务和AOP来实现的。也就是说如果你数据库用的存储引擎不支持事务,那

Spring事务就肯定没有的。(声明式事务才会基于AOP,编程式事务只是基于数据库的事务)

首先它会对使用了@Transitional注解的Bean(怎么判断Bean上是否有的?类、或者父类、或者接口、或

者方法中有这个注解都可以),创建一个代理对象

当调用代理对象的方法时,就会去判断方法上是否加了@Transitional

如果是,那么就用事务管理器创建一个数据库连接

并且把其自动提交置为false,变为手动提交,这是Spring重要的一步,即把事务交给Spring管理

然后就会执行SQL

执行完当前方法后,就直接提交事务

如果有异常,且这个异常是要回滚的异常,就会回滚事务,如果不是就还是直接提交

Spring事务的隔离级别对应的就是数据库的事务隔离级别

Spring事务的传播行为是Spring自己来实现的,也是Spring事务中最复杂的地方

Spring事务的传播是基于数据库连接来做的,一个事务对应着一个数据库connection

隔离级别

传播机制

声明式

@Transitional

无侵入性,但粒度大,只支持方法级别

编程式

粒度小,可以避免Spring AOP失效的问题

基于TransitionTemplate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Autowired
private TransactionTemplate transactionTemplate;
public void testTransaction() {

transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {

try {

// .... 业务代码
} catch (Exception e){
//回滚
transactionStatus.setRollbackOnly();
}

}
});
}

基于TransitionManager

1
2
3
4
5
6
7
8
9
10
11
12
13
@Autowired
private PlatformTransactionManager transactionManager;

public void testTransaction() {

TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
// .... 业务代码
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
}
}

事务失效

spring 事务失效的 12 种场景_spring 截获duplicatekeyexception 不抛异常-CSDN博客

声明式失效的场景

方法访问权限不为public,因为方法要想被Spring代理,就必须是public

方法被final修饰,被final修饰意味着不能被重写。声明式事务使用了AOP,底层是用到jdk和cglib了动态代

理,都得通过重写重写方法去实现代理

方法内部调用时,没通过代理对象调用方法,而是通过this调用

Bean没被Spring所管理

多线程事务

表不支持事务

事务回滚不了的场景

错误的传播特性

自己捕获了异常,且不抛出

自定义异常

手动抛了别的异常,默认情况下不指定只会抛运行时异常

嵌套事务回滚多了