Einfache Transaktionen mit Spring JDBC?
-
06-07-2019 - |
Frage
ich auf einer Java-Anwendung arbeite, das Spring verwendet IoC und JDBC-Template-Klassen. Ich habe eine DAO-Klasse, die 4-Methoden hat: m1 () bis m4 (). m1 führt mehrere Einfügungen und Aktualisierungen auf dem Tisch t1, m2 auf Tabelle t2, m3 auf t3, etc.
Die DAO-Methoden wie folgt verwendet werden:
while(true)
{
//process & generate data
dao.m1(data1);
dao.m2(data2);
dao.m3(data3);
dao.m4(data4);
//sleep
}
Ich möchte, dass die db Operationen im Rahmen der 4 aufeinander folgenden Methode ruft Atom zu sein, entweder alle vier Tabellen werden aktualisiert erfolgreich oder keine. Also, wenn ein Fehler auftritt, während Operationen in m3 () durchgeführt wird, möchte ich alle Änderungen (Updates & Einsätze) in m2 und m1 durchgeführt, um ein Rollback.
Das Gleiche gilt für Frühling können Sie tun es die folgende Art und Weise?
while (true)
{
//process & generate data
transaction = TransactionManager.createNewTransaction();
transaction.start()
try
{
dao.m1(data1);
dao.m2(data2);
dao.m3(data3);
dao.m4(data4);
}
catch(DbUpdateException e)
{
transaction.rollBack();
}
transaction.end();
// sleep
}
oder gibt es bessere Möglichkeiten, es zu tun?
Lösung
Für Vollständigkeit, würde die programmatische Lösung sein:
private TransactionTemplate transactionTemplate;
public setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
...
while (true) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
dao.m1(data1);
dao.m2(data2);
dao.m3(data3);
dao.m4(data4);
} catch(DbUpdateException e) {
status.setRollbackOnly();
}
}
});
}
Andere Tipps
Ja Frühling können Sie href="http://static.springframework.org/spring/docs/2.5.x/reference/transaction.html" zum programmatisch Transaktionen steuern .
Persönlich ziehe ich es deklarative Transaktionen Anmerkungen mit , die so geht:
public void runBatchJob() {
while (true) {
// generate work
doWork(unitOfWork);
}
}
@Transactional
private void doWork(UnitOfWork work) {
dao.m1(data1);
dao.m2(data2);
dao.m3(data3);
dao.m4(data4);
}
, wo die DAO-Funktionen sind definiert:
@Transactional
public void m1(Data data) {
...
}
Dies erfordert in der applicationContext.xml :
<tx:annotation-driven/>
deklarative Transaktionen können erklärt werden, um eine Transaktion zu verlangen, erfordert eine neue Transaktion, Unterstützung Transaktionen usw. Rollback auftreten, wenn ein Block mit Anmerkungen versehen mit @Transactional
ein RuntimeException
wirft.
Frühling kann dies für Sie behandelt alle von @Transactional wie erklärt oder in XML zu verwenden, wenn Sie es vorziehen.
Der Import Sache richtig zu machen, ist die Art von Transaktions Propagation Sie möchten die alle auf Ihre Anwendung ab.
Standardmäßig wird eine Transaktion gestartet werden, wenn man nicht vorhanden ist, und wird eine vorhandene Transaktion wiederverwenden, wenn man bereits gestartet wurde. Dies ist das Verhalten, das Sie wollen, wenn Sie alle 4 DAOs wollen atomar sein.
Setzen Sie @Transactional auf einer Klasse, die die DAO-Methoden verwalten aufgerufen (MyService) - etwas unterhalb dieser Schicht nun Teil nimmt in dieser Transaktionsgrenze wird.
heißt:
@Transactional
public void m1(Data data) {
...
}
@Transactional
public void m2(Data data) {
...
}
Auf diese im Code ist völlig unnötig.