尝试在线程中运行事务时,“EntityManagerFactory已关闭”

时间:2017-06-13 21:01:07

标签: spring multithreading transactions spring-aop spring-transactions

我正在使用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,为什么错误以及如何解决?

0 个答案:

没有答案