Transactional事务失效自检流程

Spring 的传播行为

1
2
3
4
5
6
7
8
9
 public enum Propagation {
REQUIRED(0),
SUPPORTS(1),
MANDATORY(2),
REQUIRES_NEW(3),
NOT_SUPPORTED(4),
NEVER(5),
NESTED(6);
}
  • REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务。则创建一个新事务。

  • SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式继续运行。

  • MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

  • REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。

  • NOT_SUPPORTED :以非事务方式运行,如果当前存在事务,则把当前事务挂起。

  • NEVER :以非事务方式运行,如果当前存在事务,则抛出异常。

  • NESTED :如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 REQUIRED 。

动态代理

在继续探究前,先简单带过一下动态代理。
代理模式主要功能是为了增强一个类中的方法诞生的一种设计模式。
而代理模式分为动态代理和静态代理,动态代理的代理类是在运行时生成的,而静态代理是在编译时生成的。动态代理可以分为基于接口的JDK动态代理和基于类的Cglib动态代理。
下面讲解一下基于JDK的动态代理:
在java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过这个类和这个接口可以生成JDK动态代理类和动态代理对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public interface Person {
void work();
}

public class Student implements Person {
@Override
public void work() {
System.out.println("读书");
}
}

public class MyInvocationHandler implements InvocationHandler {
//增强的目标类
private Person person;

public MyInvocationHandler(Person person) {
this.person = person;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("先吃饭-----再看书");
method.invoke(person, args);
return null;
}
}

public class Main {
public static void main(String[] args) {
Person person = new Student();
MyInvocationHandler myInvocationHandler = new MyInvocationHandler(person);
System.out.println(Arrays.toString(Student.class.getInterfaces()));
Person proPerson = (Person) Proxy.newProxyInstance(Student.class.getClassLoader(), Student.class.getInterfaces(), myInvocationHandler);
proPerson.work();
}
}

//结果为: 先吃饭-----再看书 读书

动态代理的坑

Spring事务是基于动态代理实现的。那么,Spring事务失效的真正原因和动态代理有什么关联呢?