Спящий режим: транзакция не была успешно запущена (многопоточное веб-приложение). - PullRequest
1 голос
/ 25 февраля 2010

У меня серьезная проблема в веб-приложении, использующем поток для прослушивания пакетов на порту и обработки этих пакетов.

Обработка пакета включает в себя транзакции базы данных, поэтому в основном это выглядит так:


Thread:
run () {
  try {
    ...
    fireMessageEvent(data);
    ...
  } catch (Exception e) {
  }
}

fireMessageEvent(data) {
  someclass.messageArrived(data);
}

SomeClass:
messageArrived(Data data) {
  try {
    someOtherClass.setData(data);
  } catch (Exception e) {
  }
}

SomeOtherClass:
setData (Data data)
{
  try {
   ..
   processDataPart1(data);
   processDataPart2(data);
   ..
  } catch (Exception e) {
  }
}

processDataPart1(data)
{
    daolayer.getSomeObjectFromDatabase(x);
    ..
    daolayer.save(y);
    ..
    someotherDaolayer.update(a);
    ..
}

processDataPart2(data)
{
    daolayer.getSomeObjectFromDatabase(x);
    ..
    daolayer.save(y);
    ..
    someotherDaolayer.update(a);
    ..
    daolayer.save(b);
    ..
}


Проблема в том, что я получаю исключение «Транзакция не была успешно запущена». Также интересно, что исключение перехватывается перехватом в потоке и, следовательно, не сохраняет данные (вероятно, из-за отката.?). На данный момент я создаю еще один фиктивный объект для сохранения в базе данных, а затем удаляю его, чтобы при возникновении исключения его фиктивный объект не сохранялся, а предыдущие объекты сохранялись.

Может кто-нибудь помочь с этим? Кто-нибудь сталкивался с такой же проблемой?

Вот подробности исключения:

2010-02-25 10:30:33,759 INFO [packetInfo log] - Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started
2010-02-25 10:30:33,759 INFO [packetInfo log] - org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:659)
2010-02-25 10:30:33,759 INFO [packetInfo log] - org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:732)
2010-02-25 10:30:33,759 INFO [packetInfo log] - org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:701)
2010-02-25 10:30:33,759 INFO [packetInfo log] - org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321)
2010-02-25 10:30:33,759 INFO [packetInfo log] - org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
2010-02-25 10:30:33,774 INFO [packetInfo log] - org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
2010-02-25 10:30:33,774 INFO [packetInfo log] - org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
2010-02-25 10:30:33,774 INFO [packetInfo log] - com.comp.projectx.service.lear.communicator.AriadneListenerServiceImplementation$$EnhancerByCGLIB$$e5054dfb.setData()
2010-02-25 10:30:33,774 INFO [packetInfo log] - com.comp.projectx.service.lear.communicator.PLCListenerServiceImplementation.messageArrived(PLCListenerServiceImplementation.java:153)
2010-02-25 10:30:33,774 INFO [packetInfo log] - com.comp.projectx.service.lear.communicator.Listener.fireMessageEvent(Listener.java:229)
2010-02-25 10:30:33,774 INFO [packetInfo log] - com.comp.projectx.service.lear.communicator.Listener.run(Listener.java:94)

Конфигурация в web.xml:

    hibernateFilter : org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
    hibernateFilter url-pattern: *.95
    hibernateFilter url-pattern: /dwr/*
    lazyLoadingFilter: org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
    lazyLoadingFilter url-pattern: /*

Конфигурация Hibernate:


    jee:jndi-lookup id="dataSource" jndi-name="/jdbc/kernstreamDS" resource-ref="true" expected-type="javax.sql.DataSource" 

    bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
        property name="dataSource" ref="dataSource" 
    bean

    bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"

В слое Дао для сохранения объекта:


    getSession().saveOrUpdate(resultObj);

для извлечения:


    List resultObj = getSession().createCriteria(Lot.class)
            .add(Restrictions.eq("publicId", publicId)).list();

Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

4 голосов
/ 26 февраля 2010

Я решил проблему. Если у кого-то еще была такая же проблема, вот как я это сделал.

В основном на уровне dao использовалось управление транзакциями Spring, а в других местах - управление транзакциями в спящем режиме. Смешивание двух не очень хорошая идея. Таким образом, изменив в слое дао от использования

getSession () saveOrUpdate (...).

до

getHibernateTemplate () saveOrUpdate (...).

решил проблему.

Спасибо всем за комментарии.

0 голосов
/ 17 мая 2011

У меня была похожая проблема, в моей ситуации была проблема в соединении, очевидно, если нет соединения, то нет сеанса, если нет сеанса, нет транзакции.

    try {
            session = HibernateSessionFactory.getSessionFactory()
                    .openSession();
            session.beginTransaction();
            StringBuffer qry = new StringBuffer();
            qry.append(" select a.customer_key from customer as a where a.name= '"+siteName+"' ");
            query = session.createSQLQuery(qry.toString());
            customerList = (ArrayList) query.list();                
            session.getTransaction().commit();
        } catch (HibernateException hex) {
            session.getTransaction().rollback();                
            String msg = "Error occured in getCustomerId Cause: " + hex;
            logger.error(msg);
            throw new DAOException(msg);
        }finally{
            if(session != null){
                session.close();
            }
        }

В приведенном выше фрагменте происходит откат сеанса, который даже не существует. В результате транзакция не была успешно запущена. Поэтому я добавил вложенный блок try catch, чтобы избежать этой ошибки.

Итак, мой модифицированный код выглядел примерно так:

try {
            session = HibernateSessionFactory.getSessionFactory()
                    .openSession();
            session.beginTransaction();
            StringBuffer qry = new StringBuffer();
            qry.append(" select a.customer_key from customer as a where a.name= '"+siteName+"' ");
            query = session.createSQLQuery(qry.toString());
            customerList = (ArrayList) query.list();                
            session.getTransaction().commit();
        } catch (HibernateException hex) {
        try{
            session.getTransaction().rollback();                
        }catch(Exception e){
        //just log warn
        }
            String msg = "Error occured in getCustomerId Cause: " + hex;
            logger.error(msg);
            throw new DAOException(msg);
        }finally{
            if(session != null){
                session.close();
            }
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...