spring 会话/实体管理器已关闭

rqmkfv5c  于 2022-10-31  发布在  Spring
关注(0)|答案(2)|浏览(151)

我有这个Hibernate dao,在我的本地机器上测试时它工作得很好。但是对于一些事务,它抛出IllegalStateException。我相信这是因为多个用户同时点击它。(我可能错了)。

更新付款方式

@Repository
public class UpdatePaymentImpl implements UpdatePayment {

    @Autowired
    SessionFactory sessionFactory;
    Session session;
    Transaction trans;

    private static final long LIMIT = 100000000000L;
    private static final long LIMIT2 = 10000000000L;
    private static long last = 0;

    public static long getUniqueID() {
        // 10 digits.
        long id = (System.currentTimeMillis() % LIMIT) + LIMIT2;
        System.out.println("id"+id);
        System.out.println("system time"+System.currentTimeMillis());
        System.out.println("milssiiiiii=============="
                + System.currentTimeMillis());
        if (id <= last) {
            id = (last + 1) % LIMIT;
        }
        return last = id;
    }

    public PaymentResponse updatePayment(@RequestBody FcgoUpdateParam updateParam) {
        FcgoUpdateParam fcgoUpdateParam= new FcgoUpdateParam();
        Double amountPaid=Double.parseDouble(updateParam.getAmountPaid());
        String depositSlioNo=updateParam.getVoucherno();
        String masterId= updateParam.getMasterId();
        String advCode=updateParam.getAdvCode();

        PaymentResponse paymentResponse = new PaymentResponse();

        long uuid = getUniqueID();

        try{

            System.out.println("generated uuid "+uuid);

            DateFormat dateFormat =new SimpleDateFormat("dd-MMM-yy h.mm.ss.000000000 a");
            SimpleDateFormat dms = new SimpleDateFormat("dd-MM-yyyy");
            String cdate = updateParam.getChallanDate();
            Date ddate= dms.parse(cdate);
            String challandate = dateFormat.format(ddate);

            String office = updateParam.getOffice();
            String username = updateParam.getUsername();
            Long id = getIdOnChallanTable()+1L;

            String challanid = String.valueOf(uuid);
            ChallanEntity challanEntity = new ChallanEntity();
            challanEntity.setAdvtcode(updateParam.getAdvCode());
            challanEntity.setAmount(amountPaid);
            challanEntity.setName(updateParam.getName());
            challanEntity.setOffice(office);
            challanEntity.setUsername(username);
            challanEntity.setStatus(updateParam.getStatus());
            challanEntity.setChallandate(challandate);
            challanEntity.setChallanid(uuid);
            challanEntity.setChallantime("null");
            challanEntity.setVoucherno(updateParam.getVoucherno());

            System.out.println(challanEntity.getId());

            System.out.println("challan saved");

            session=sessionFactory.openSession();
            trans=session.beginTransaction();

            Query query= session.createQuery("update CandidateappearagainstadvtcodeEntity cd set 

            cd.paymentstatus='Completed',cd.amountpaid=:depoFee,cd.challanid=:challanid where
             cd.studentmasterid=:masterid and cd.advertisementcode=:advCode");
            System.out.println(updateParam.getAdvCode());
            query.setParameter("depoFee",updateParam.getAmountPaid());
            query.setParameter("challanid",challanid);
            query.setParameter("masterid",masterId);
            query.setParameter("advCode",advCode);
            Query query1 =session.createQuery(" update CandidateappeartoadvtnumberEntity cnd

            set cnd.paymentstatus='Completed', cnd.depositedfee=:depofee where
             cnd.studentmasterid=:masterid
            and cnd.advertisementcode=:advcode");
            String masterId1= updateParam.getMasterId();
            String advCode1=updateParam.getAdvCode();
            System.out.println("updateCandidateappearagainstadvtcodeEntity ");

            query1.setParameter("depofee",amountPaid);
            query1.setParameter("masterid",masterId1);
            query1.setParameter("advcode",advCode1);

            //added code
            final long start = System.nanoTime();
            System.out.println("before executing excute update queries");
            System.out.println("checking update query timings");

            query.executeUpdate();
            query1.executeUpdate();
            //added code
            final long end = System.nanoTime();
            System.out.println("after executing two update queries, it took: " +
            ((end - start) / 1000000) + "ms");

            //printing all values for test
            //printing for candidateappearagainstcode table
            System.out.println("printing candidate appear against code table");
            System.out.println("the received challan id is: " +challanid);
            System.out.println("the received deposited fee is :"+amountPaid);
            System.out.println("the received advt code is : "+advCode);
            System.out.println("the received master id is : "+masterId);

            System.out.println("values committed on psc database");
            try {
                final String uri = "http://xx.x.x.xx:xxxx/FcgoApi/api/savePayment";
                RestTemplate restTemplate = new RestTemplate();
                paymentResponse = restTemplate.postForObject(uri, updateParam,
                PaymentResponse.class);
                if (paymentResponse.getVoucherNo() != null) {
                    challanEntity.setVoucherno(paymentResponse.getVoucherNo());
                    session.save(challanEntity);
                    session.update(challanEntity);
                    trans.commit();
                    return paymentResponse;
                }else {
                    trans.rollback();
                }
            }catch (Exception ex){
                ex.printStackTrace();
                trans.rollback();
            }
        }catch (Exception e){
            System.out.println("update error " +e);
            trans.rollback();

        }finally {
            session.close();
        }
        return paymentResponse;
    }

    // [...]
}

应用程序上下文.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="org.springframework.beans.factory.config.
        PropertyPlaceholderConfigurer">
        <property name="location">
            <value>/WEB-INF/db.properties</value>
        </property>
    </bean>
    <bean id="sessionFactory" 
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.connection.url">
                    jdbc:oracle:thin:@x.x.x.x:1521:xxx</prop>
                <prop key="hibernate.connection.driver_class">
                    oracle.jdbc.driver.OracleDriver</prop>
                <prop key="hibernate.c3p0.timeout">18000</prop>
            </props>
        </property>
        <property name="packagesToScan">
            <list>
                <value>com.psc</value>
            </list>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.
        orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    <bean id="dataSource" class="org.springframework.jdbc.
        datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

</beans>

错误日志:

java.lang.IllegalStateException: Session/EntityManager is closed
        at org.hibernate.internal.AbstractSharedSessionContract.
        checkOpen(AbstractSharedSessionContract.java:328)
        at org.hibernate.engine.spi.SharedSessionContractImplementor
        checkOpen(SharedSessionContractImplementor.java:126)
        at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:669)
        at org.hibernate.internal.SessionImpl.save(SessionImpl.java:665)
        at org.hibernate.internal.SessionImpl.save(SessionImpl.java:660)
        at com.psc.dao.UpdatePaymentImpl.updatePayment(UpdatePaymentImpl.java:127)
        at com.psc.services.UpdatePaymentServiceImpl.updatePayment
        (UpdatePaymentServiceImpl.java:26)
        at sun.reflect.GeneratedMethodAccessor92.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
        at java.lang.reflect.Method.invoke(Method.java:508)
        at org.springframework.aop.support.AopUtils
        .invokeJoinpointUsingReflection(AopUtils.java:333)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.
        invokeJoinpoint(ReflectiveMethodInvocation.java:190)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.
        proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1
        .proceedWithInvocation(TransactionInterceptor.java:99)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.
        invokeWithinTransaction(TransactionAspectSupport.java:282)
        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.$Proxy32.updatePayment(Unknown Source)
        at com.psc.controls.UpdatePayment.updatePayment(UpdatePayment.java:26)
        at sun.reflect.GeneratedMethodAccessor91.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
        at java.lang.reflect.Method.invoke(Method.java:508)
        at org.springframework.web.method.support.
        InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
        at org.springframework.web.method.support.
        InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
        at org.springframework.web.servlet.mvc.method.annotation.
        ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
        at org.springframework.web.servlet.mvc.method.annotation.
        RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
        at org.springframework.web.servlet.mvc.method.annotation.
        RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
        at org.springframework.web.servlet.mvc.method.
        AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
        at org.springframework.web.servlet.DispatcherServlet.
        doDispatch(DispatcherServlet.java:963)
        at org.springframework.web.servlet.DispatcherServlet
        .doService(DispatcherServlet.java:897)
        at org.springframework.web.servlet.FrameworkServlet
        .processRequest(FrameworkServlet.java:970)
        at org.springframework.web.servlet.FrameworkServlet
        .doPost(FrameworkServlet.java:872)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
        at org.springframework.web.servlet.FrameworkServlet
        .service(FrameworkServlet.java:846)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
        (ApplicationFilterChain.java:231)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter
        (ApplicationFilterChain.java:166)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
        (ApplicationFilterChain.java:193)
update error java.lang.IllegalStateException: org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl@4bbb6b39 is closed
toiithl6

toiithl61#

你不能像那样使用SessionTransaction作为你的dao的类成员。Session/EntityManager被认为是由工作单元限定的,它们不是线程安全的。
在您当前的状态下,由于Spring DI将bean创建为单例,如果两个线程同时使用dao,则第二个线程将覆盖SessionTransaction成员,这就是为什么我认为您会得到IllegalStateExcepion。
您必须通过在方法中将它们用作变量来使它们成为线程范围,或者,如果您不需要Hibernate的特定方法,则可以在Spring中进行完整的JPA配置,并使用@PersistenceContext/@PersistenceUnit让框架处理该问题。

lb3vh1jj

lb3vh1jj2#

Spring将创建DA类的一个单例副本。在多线程的情况下,当线程t1正在处理一个会话/事务,而共享同一个会话/事务的线程t2可能会关闭它。因此,请确保在本地变量中声明这些变量。变量声明的作用域在这里很重要。

相关问题