Spring3 's @Transactional @Geplante nicht verpflichtet DB?
Dies ist mein 1. mal versucht Spring3 s @Eingeplant , aber ich kann nicht verpflichten zu DB. Das ist mein code :
@Service
public class ServiceImpl implements Service , Serializable
{
@Inject
private Dao dao;
@Override
@Scheduled(cron="0 0 * * * ?")
@Transactional(rollbackFor=Exception.class)
public void hourly()
{
//get xxx from dao , modify it
dao.update(xxx);
}
}
Ich denke, es sollte funktionieren , ich kann es sehen beginnt-bis stündlich und laden xxx von DB , aber die Daten ist nicht verpflichtet, DB.
Gab es tx:annotation-driven
im Frühjahr xml :
<bean id="entityManagerFactoryApp" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="myapp"/>
</bean>
<bean id="transactionManagerApp" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryApp" />
</bean>
<tx:annotation-driven transaction-manager="transactionManagerApp" />
Kann jemand mir sagen, was ich hier verpasst ?
Habe ich eine " dirty' Lösung :
@Service
public class ServiceImpl implements Service , Serializable
{
@Inject
private Dao dao;
@Inject
@Qualifier("transactionManagerApp")
private PlatformTransactionManager txMgrApp;
@Override
@Scheduled(cron="0 0 * * * ?")
@Transactional(rollbackFor=Exception.class)
public void hourly()
{
final TransactionTemplate txTemplateApp = new TransactionTemplate(txMgrApp);
txTemplateApp.execute(new TransactionCallbackWithoutResult()
{
@Override
protected void doInTransactionWithoutResult(TransactionStatus status)
{
//get xxx from dao
dao.update(xxx);
}
});
}
}
Es funktioniert hier , aber es ist so überflüssig , was den code schwieriger zu Lesen.
Ich Frage mich, warum TransactionManager ist nicht injiziert (und geöffnet) in dem vorherigen code-Schnipsel?
Vielen Dank !
- Ein bisschen off-topic, aber Sie brauchen nicht
rollbackFor
für@Transactional
. Rollback erfolgt immer implizit zur Laufzeit Ausnahmen. - Ich habe versucht, Ihr dirty-Lösung, aber es funktioniert nicht. irgendeine Idee warum?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Werden Sie wahrscheinlich festgestellt haben, dass diese aus oder bewegt sich auf (ich hoffe ja), aber zum Wohle der anderen:
Den
@Transactional
Anmerkung sagt Feder zu wickeln Sie Ihre original -ServiceImpl
bean mit einem dynamischen proxy, der führt auch 'Service
' (standardmäßig Frühjahr proxies die Schnittstelle, nicht die Implementierung). Dieser proxy wird transparent behandeln die Erstellung und commit/rollback der Transaktion beim Aufrufhourly()
auf dem proxy. Allerdings, wenn Sie anrufenhourly()
direkt auf Ihre Umsetzung (das ist das, was oben), wird der proxy umgangen wird, so gibt es keine Transaktion.http://blog.springsource.org/2012/05/23/understanding-proxy-usage-in-spring/
Die Lösung ist entweder
dao.update(xxx);
über die Service-Schnittstelle nicht direkt auf deine Umsetzung (und somit der Umweg über den Proxyserver). Grundsätzlich müssen Sie zu bewegen, die@Scheduled
- Methode, zum anderen bean.Ich hoffe das ist klar genug!
Wenn Sie annotation-driven-Unterstützung, es funktioniert nur mit Klassen erzeugt in diesem Kontext. Meine Wette ist, dass ServiceImpl ist nicht in demselben Kontext wie Ihre Transaktions-manager (entweder direkt oder durch die annotation Scannen).
Ich hatte das gleiche problem und nach einiger Zeit auf, ich erkannte, dass ich eine Ausnahme nach der dao.update () - Aufruf in einigen unabhängigen code, der nicht check null-Wert - so ist es einfach brach der Transaktion.
Es war kein stackTrace drucken, weil es behandelt worden ist, sowie durch die Feder (einige catch-block).
Ich verbrachte eine Weile an.
So einfach stellen Sie sicher, dass Ihre Transaktion-Methode abgeschlossen ist, bis zu seinem Ende.
Hoffe, es wird jemand helfen.
Yosi Lev