问题分析 之 no transaction is in progress

文章目录

  1. 1. 问题现象
  2. 2. 示例代码 - Proxy

问题现象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:301)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
at $Proxy34.flush(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
at $Proxy34.flush(Unknown Source)
... 53 more

示例代码 - Proxy

1
2
3
4
5
6
7
8
9
10
11
public class classA {

public void doA {
this.doB();
}

@Transaction
public void doB{
// do save or update
}
}

问题分析:
如上代码段,由于doB为对象内方法,而Spring事务的开启依赖到AOP(Proxy),在doA方法调用doB方法时,
由于是对象内的方法调用,造成doB方法的@Transaction不会被Proxy对象代理,进而造成Transaction失效。

解决方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ClassA {
private ClassB classB;

public void doA() {
classB.doB();
}
}

public class ClassB {

@Transaction
public void doB() {
// do save or update
}

}

将需要事务的方法doB通过Proxy进行代理,doA在使用时则是通过Spring开启事务的代理进行的调用。


观点仅代表自己,期待你的留言。