我正在使用Spring 4.3.8.RELEASE。我对SPring的@Transactional注释以及它在线程生成期间应用时非常困惑。我有这个班级
@Service("MyServiceImpl")
@Transactional
public class MyServiceImpl
{
@Override
public MyObject myMethod(...) {
...
runPrivateMethod();
}
private void runPrivateMethod()
{
...
for (final User user : users)
{
final Thread otherUserThread = new Thread(new Runnable()
{
@Override
public void run()
{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
LOG.error(e.getMessage());
}
m_otherSvc.doStuff(user.getId());
}
});
otherUserThread.start();
} // for
} //
当执行“m_otherSvc.doStuff”时,我通常(但并非总是)看到此错误
Exception in thread "Thread-8" org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is java.lang.IllegalStateException: EntityManagerFactory is closed
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:431)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:447)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:277)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy83.findById(Unknown Source)
at org.mainco.subco.thirdpartyItem.service.thirdpartyAPIServiceImpl.getUserData(thirdpartyAPIServiceImpl.java:238)
at org.mainco.subco.thirdpartyItem.service.thirdpartyAPIServiceImpl.doStuff(thirdpartyAPIServiceImpl.java:111)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy89.doStuff(Unknown Source)
at org.mainco.subco.classroom.service.MyServiceImplImpl$8.run(MyServiceImplImpl.java:1672)
at java.lang.Thread.run(Thread.java:745)
虽然“m_otherSvc.doStuff”不是@Transactional,但它会调用
public void doStuff(final String userId)
{
...
final User user = m_userSvc.findById(userId);
“m_userSvc.findById”标记为@Transactional,为什么错误以及如何解决?