Ich habe das folgende Szenario. Ich benutze JPA, Spring:Propagation.REQUIRES_NEW erstellt keine neue Transaktion im Frühjahr mit JPA
@Autowired
SampleService service;
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void PerformLogic(LogicData data) throws SIASFaultMessage
{
SampleObject so = createSampleObject();
try{
.//do some logic to persist things in data
.
.
persistData(data);
.
.
.
updateSampleObject(so);
}
catch(Exception){
updateSampleObject(so);
throw new SIASFaultMessage();
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public createSampleObject()
{
SampleObject so = new SampleObject();
.
.//initialize so
.
service.persist(so);
return so;
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public updateSampleObject(SampleObject so)
{
service.persist(so);
return so;
}
Wenn alles funktioniert, bleiben Daten in der Datenbank ohne Probleme persistent. Wenn jedoch eine Ausnahme ausgelöst wird, muss die Methode updateSampleObject (so) die Informationen in der Datenbank beibehalten. Das ist nicht was passiert. Wenn eine Ausnahme ausgelöst wird, wird auch die Methode updateSampleObject zurückgesetzt, was ich nicht brauche. Ich brauche, dass diese beiden Methoden (createSampleObject und updateSampleObject) die ganze Zeit beibehalten, egal ob eine Ausnahme ausgelöst wurde oder nicht. Wie kann ich das erreichen?
Außerdem, wenn ich die Methoden anotate createSampleObject und updateSampleObject mit:
@Transactional(propagation = Propagation.NEVER)
die Idee ist, dass eine Ausnahme ausgelöst wird, und ich bekomme keine Ausnahme ausgelöst. Wo ist das Problem? Analizing die Protokolle sehe ich diese Zeile:
org.springframework.orm.jpa.JpaTransactionManager ==> Creating new transaction with name [com.test.PerformLogic]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT....
, die diese Transaktion Mittel erstellt, aber ich sehe keinen Hinweis auf die andere Transaktion.
Dies ist der Teil meiner Konfigurationsdatei für den Frühling in Bezug auf Transaktionen
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="packagesToScan" value="cu.jpa"/>
<property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">${hdm2ddl.auto}</prop>
</props>
</property>
<property value="/META-INF/jpa-persistence.xml" name="persistenceXmlLocation"/>
<property name="persistenceUnitName" value="jpaPersistenceUnit"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="nestedTransactionAllowed" value="true" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
Danke, das war es. Ich werde die Frühjahrsdokumentation genauer unter die Lupe nehmen. Wissen Sie, ob es einen Weg gibt, dass die Transaktionen nicht auf Proxy-basiert, sondern auf der Methode funktionieren? –
@AlfredoA. Es ist möglich, wenn Sie das Webzeitverhalten von AspectJ verwenden, um den Code byteweise zu laden, wodurch die Notwendigkeit von Proxies, wie oben erwähnt, entfällt. Auf diese Weise kann die Transaktionsmethode foo() der Klasse A die Transaktionsmethode bar(), ebenfalls der Klasse A, aufrufen, und bar() wird innerhalb ihrer eigenen Transaktion ausgeführt. Weitere Informationen hierzu finden Sie in der oben verlinkten Spring Framework-Dokumentation. – Aquarelle
Danke eine Tonne.Ich habe viel gesucht, wenn die Transaktion ausgeführt wird, da ich zwei verschiedene Transaktionen habe, von denen eine vom Ergebnis anderer abhängt. Es hat mit "Required" & "Requires_New" funktioniert aber nur wenn ich dann in andere Beans lege. –