2012-04-16 9 views
8

mam migracji mojego projektu od wiosny 3.0 + hibernacji 3.6.x do S3.1 + H4.1Wiosna 3,1 + Hibernate 4.1 Propagation.Supports problem

mojego nowego kodu jest następujący

<context:component-scan base-package="x.y.z"> 
</context:component-scan> 

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="hibernateProperties"> 
<props> 
    <prop key="hibernate.dialect">org.hibernate.dialect.x</prop> 
    <prop key="hibernate.show_sql">true</prop> 
    <prop key="hibernate.hbm2ddl.auto">update</prop> 
    <prop key="hibernate.show_sql">true</prop> 
    </props> 
    </property> 
     <property name="annotatedClasses"> 
     <list> 
     <value>x.y.z.entities.Student</value>   
     </list> 
    </property> 
    </bean> 

<bean id="transactionManager" 
      class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory"/> 
    </bean> 

<aop:config> 
    <aop:pointcut id="daoServicePoint" 
      expression="execution(* x.y.z.StudentDao.*(..))"/> 
    <aop:advisor advice-ref="txAdvice" pointcut-ref="daoServicePoint"/> 
    </aop:config> 

    <tx:advice id="txAdvice" transaction-manager="transactionManager"> 
    <tx:attributes> 
     <tx:method name="save*" propagation="REQUIRED"/> 
     <tx:method name="update*" propagation="REQUIRED"/> 
     <tx:method name="delete*" propagation="REQUIRED"/> 
    <tx:method name="get*" propagation="SUPPORTS" read-only="true"/> 
    </tx:attributes> 
    </tx:advice> 

Podczas uruchamiania metody getStudent znacznik jako podpory i tylko do odczytu dostaję

org.hibernate.HibernateException: No Session found for current thread 
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97) 
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1024) 

kiedyś było ok z wiosny 3.0 i Hibernate 3.6.x teraz został zmieniony. Zwalniam od wiosennych forów, które kosić potrzebuję transakcji znacznika WYMAGANE, jeśli potrzebuję użyć sessionFactory.getCurrentSession();

Użyłem techniki niższego poziomu, aby uzyskać maksymalną prędkość współbieżną w moim kodzie. Podczas wykonywania czynności, które wymagają kilku GET/zapisać/Update/zapytań zrobiłem to w następujący sposób:

  1. zwaną metodę oznaczoną jako SUPPORTS.
  2. Wykonano wszystkie zapytania get, które są również oznaczone jako pierwsza metoda SUPPORTS w .
  3. następnie uruchomione zapytania oznaczone jako REQUIRED w tej samej metodzie i jest to punkt , w którym rozpoczyna się moja uruchamiana wstecz transakcja.

Poprawiłem wydajność za pomocą tej techniki, ale oznaczenie wszystkich moich metod jako WYMAGANE powoduje ich zniszczenie.

Jak obejść to?

+0

Określ wydajność "niszczy". Ta "technika niższego poziomu" nie wygląda na to, że da ci znaczną poprawę wydajności, jeśli w kroku 3 nadal musisz otworzyć transakcję, może z wyjątkiem podmiotów załadowanych w kroku 2, które nie podlegają brudnemu sprawdzeniu i buforowanie. A może poprawa wydajności, którą zobaczyłeś w systemie jako całości, z powodu wielu nawoływań do metod, które nigdy nie dotarły do ​​kroku 3? –

+0

Z ciekawości: czy zmierzyłeś przyrost wydajności swojej małej sztuczki? Wątpię, żeby to było warte wysiłku, chyba że masz poważne wymagania dotyczące wydajności swojego produktu. –

+0

@RasmusFranke, Na szczęście nie jest to coś, co wymyśliłem. Po prostu przeczytałem ten artykuł. http://www.ibm.com/developerworks/java/library/j-ts5/index.html –

Odpowiedz

0

Myślę, że nadal można oznaczyć transakcję jako tylko do odczytu. nie jestem pewien, czy ma to wpływ na wydajność.

+0

Nie. Nie możesz. –

+1

Dlaczego? używam @Transactional (readOnly = true) i działa dobrze z Hibernate 4 i wiosną 3.1 –

+0

Przepraszam, bo możesz :) –

3

I napotkał ten sam problem podczas eksperymentowania z wiosny i Hibernacja 3/4.

Wygląda na to, że jest to znany problem, który jest opisany w poniższym linku JIRA.

https://jira.springsource.org/browse/SPR-9020

Wygląda Hibernate 4 wersja SpringSessionContext nie otwiera nową sesję, jeśli nie istnieje żaden transakcja/sesja otwarta, a zwana metoda @Transactional jest skonfigurowany z propagacji = Propagation.SUPPORTS.

+0

to też mi się przydarza ... co zrobiłeś? – thiagoh

+0

@thiagoh Przepraszam za spóźnioną odpowiedź.Nie miałem potrzeby pracy nad rozwiązaniem tego problemu, ponieważ nie napotkałem problemu. Po prostu szukałem powodu, dla którego to nie zadziałało. Istnieje kilka sugestii, jak obejść ten problem w sekcji komentarzy JIRA, do której się odwołałem. Jedną z nich jest zmiana propagacji na inną (np. PROPAGATION_REQUIRED). Druga to implementacja niestandardowej klasy CurrentSessionContext, która tworzy sesję w tym przypadku i powiązanie jej z produktem SessionFactory, którego zamierzasz użyć. – mess

Powiązane problemy