Piszę prostą aplikację (Spring + Hibernate + PostgreSql db). Po prostu próbuję zbudować przykładowy obiekt i utrzymywać go w db.Wiosenna transakcja - automatyczne wycofywanie wcześniejszych aktualizacji db, gdy jedna aktualizacja bazy danych nie powiedzie się
uruchomić prostą klasę Java główne metody gdzie mam załadowany ApplicationContext i mam odniesienie do klasy usług, jak poniżej kontekście
TestService srv = (TestService)factory.getBean("testService");
Application - Kontekst:
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactoryVsm" />
</bean>
<bean id="testService" class="com.test.service.TestServiceImpl">
<property name="testDao" ref="testDao"/>
</bean>
<bean id="testDao" class="com.test.dao.TestDaoImpl>
<property name="sessionFactory" ref="sessionFactoryVsm"/>
</bean>
W TestService wstrzyknąłem TestDao. W metodzie usługi testowej skonstruowałem dla pracowników obiekty emp1 i emp2 i dzwoniąc do dao dwa razy, aby zaktualizować.
kod TestDaoImpl:
public void saveOrUpdate(BaseDomainModel baseObject) {
Session session = null;
try {
session = getHibernateTemplate().getSessionFactory().openSession();
session.saveOrUpdate(baseObject);
session.flush();
} catch (Exception e) {
logger.error("Generic DAO:saveOrUpdate::" + e);
e.printStackTrace();
} finally {
if (session != null) {
session.close();
}
}
}
Kiedy zmiana emp2 nie powinno emp1 też nie. Jak mogę to zrobić. Proszę o poradę
góry dziękuję
Aktualizacja:
Thanks Nanda. Próbowałem transakcji deklaratywnej. Ale to nie działa. emp1 zostaje utrwalone i nie jest wycofywane, drugie wywołanie dao kończy się niepowodzeniem. Dodałem porady dotyczące transakcji do metody.
aby sprawdzić, czy rada transakcja jest stosowana lub nie zmieniłem rozchodzenie się "NOT_SUPPORTED". ale nadal emp1 zostaje uparty. oczekiwanie jest, że powinniśmy mieć wyjątek typu Transaction Not Supported. proszę o poradę.
AKTUALIZACJA
@seanizer - dzięki za aktualizację. Próbowałem nawet dodać
@ Transakcja (propagacja = Propagacja.NOT_SUPPORTED) publicznych void saveEmp (Employee emp) do tej metody usługi. Ale to nie zadziałało. Ponadto iterowanie kolekcji jest dobre tylko wtedy, gdy muszę zadzwonić do jednego dao. Jeśli na wypadek, gdybym musiał zadzwonić do dwóch różnych dao, aby kontynuować obj1 i obj2 - to może nie pomóc. Aby sprawdzić, czy transakcja jest stosowana, otrzymuję @Transactional (propagacja = Propagacja.NOT_SUPPORTED). Ale nadal obj1 się utrzymywał. Wątpię, czy podana konfiguracja/adnotacja xml jest poprawna. sprawdź
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactoryVsm" />
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="saveEmp" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="testServiceOperation" expression="execution(*com.test.service.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="testServiceOperation"/>
</aop:config>
Używam org.springframework.orm.hibernate3.HibernateTransactionManager dla transactionManager. Czy to jest poprawne ?
Updated
Stworzyłem moją klasę wyjątku myRuntimeExp rozciągający się od RuntimeException i rzucanie tego samego od metody Dao sposobu użytkowania. ale wciąż nie następuje wycofywanie.Wątpię, czy poprawnie podałem konfiguracje w pliku applnContext.xml. Czy ktoś może mi pomóc, w jaki sposób sprawdzić, czy porady/adnotacje dotyczące transakcji są stosowane do tej metody, czy nie? Czy jest jakiś sposób na uruchomienie go w trybie debugowania i sprawdzić
problem:
używałem
session = getHibernateTemplate().getSessionFactory().openSession();
Ale to powinno być bieżącej sesji i to działa dobrze.
session = getHibernateTemplate().getSessionFactory().getCurrentSession();
Czy pomoc w ramach wiosennej deklaracji transakcji jest w tym przypadku pomocna? – Vaandu
tak, oczywiście, zadeklaruj, że transakcja jest potrzebna na dao ORAZ na poziomie usługi. Jeśli dao wykryje, że usługa otworzyła transakcję, użyje jej zamiast tworzyć nową transakcję. – nanda
Nie zgadzam się, transakcje powinny być potrzebne w odniesieniu do metod usług, a nie metod dao. W ten sposób wywołanie usługi może być atomowe, nawet jeśli używa wielu metod dao (tak, wiem, że możesz to również osiągnąć, łącząc istniejące transakcje, ale wolę czysty rozdział warstw) –