Spring Jdcc deklarative Transaktionen erstellt, aber nichts tun

Ich habe versucht, das deklarative Transaktionsmanagement in meiner Spring-basierten Webanwendung zu konfigurieren, und es verweigert die Zusammenarbeit mit mir.

Ich habe zwei Hauptprobleme:

  1. Wenn Sie defaultAutoCommit auf unserer Datenquelle (die wir für unsere Anwendung benötigen) auf false setzen, werden alle Abfragen rückgängig gemacht, mit oder ohne Transaktionen.
  2. Transaktionen werden konfiguriert und Proxy-classn sowie Transaktions-Methoden werden erstellt, jedoch scheinen keine Transaktionen verwendet zu werden.

Das erste Problem ist ziemlich verwirrend, da jede einzelne Abfrage in der database zurückgesetzt wird. Dies schließt auch SELECT-statementen ein. Was könnte dazu führen, dass jede Abfrage in der database zurückgesetzt wird?

Was das zweite Problem betrifft, ist meine Konfiguration der Transaktionsverwaltung wie folgt umrissen:

applicationContext.xml

  <!-- the transactional advice (what 'happens'; see the  bean below) -->                            

Von allen Tutorials und Foren, die ich besucht habe, um dieses Problem zu lösen, glaube ich, dass meine Konfiguration korrekt sein sollte. Jedoch verstehe ich nicht vollständig AOP und Spring Transaktionen, so dass ich etwas Entscheidendes verpassen kann.

Wie oben erwähnt, kann ich meine Protokolle verfolgen und sehen, dass für meine Serviceklassen Proxys sowie Transaktionsmethoden erstellt werden. Wenn ich die Anwendung tatsächlich ausführe und die Protokolle zurückverfolgte, sehe ich keine statementen, die sich mit dem DataSourceTransactionManager befassen, oder Transaktionen, die erstellt, festgeschrieben, zurückgesetzt werden usw.

Es scheint mir, dass tatsächlich nichts ausgeführt wird, und ich bin schrecklich verwirrt, da ich viele verschiedene Tutorials verfolgt habe und diese vielen verschiedenen Arten versucht habe, aber es endet immer mit dieser Situation.

Ich bin auch ziemlich sicher, dass ich meine log4j Eigenschaften richtig eingerichtet habe, um Nachrichten vom DataSourceTransactionManager zu erhalten, aber ich liefere sie unten, um sicherzustellen, dass es nicht nur ein Protokollierungserrors meinerseits ist.

Mein Log4j ist mit den folgenden Loggern eingerichtet, um die Transaktionen zu verfolgen:

 log4j.logger.org.springframework=INFO, file log4j.logger.org.springframework.jdbc.datasource=DEBUG, file log4j.logger.org.springframework.transaction=DEBUG, file 

Hinweis: Ich habe den obersten Protokollierer an einem Punkt auf DEBUG ausgeführt, und dort habe ich überprüft, dass die Dienstproxys erstellt wurden.

Hat jemand irgendwelche Einsichten darüber, was passieren könnte? Ich bin im Moment ziemlich festgefahren, da ich einige mit Transaktionen verbundene Transaktionen sehe, aber ich sehe keine Anzeichen dafür, dass Transaktionen überhaupt verwendet werden.

Bearbeiten :

Zusätzliche Informationen wie von JB Nizet angefordert.

Meine gesamte Anwendung ist annotationsgesteuert und meine Service-Beans sind mit @Service versehen und werden über namenbasierte Autowiring in meine Controller eingefügt.

Das Folgende ist ein Beispiel für eine meiner Serviceklassen (Namen wurden geändert, spiegeln jedoch meine applicationContext.xml wider).

 @Service("zapService") public class ZapService { /** * Data access object which performs the database look up */ private ZapDAO zapDAO; /** * Add the given zap to the database * * @param zap a populated zap */ public void processNewZap(Zap zap) { zapDAO.processNewZap(zap); } } 

Wie Sie sehen, sind meine Serviceklassen lediglich Proxies zwischen den Controller-classn und den Dao-classn. Die DAOs sind, wo ich tatsächlich databaseverbindungen handhabe.

Ich glaube, ich habe irgendwo gelesen, dass die Transaktionstransaktionen, eher die Dao-classn, eine bevorzugte Praxis bei Transaktionen darstellen. Bitte korrigieren Sie mich, wenn ich falsch liege.

Die ZapDAO-class wird im Folgenden beschrieben.

 @Repository("zapDAO") public class ZapDAO { /** * Log4j logger for this class */ Logger logger = Logger.getLogger(ZapDAO.class); /** * Spring jdbc object to handle interacting with the database */ private JdbcTemplate jdbcTemplate; public void processNewZap(Zap zap) { ... query constructing logic ... this.jdbcTemplate.update(INSERT_ZAP_QUERY_SQL); } public void setDataSource(DataSource dataSource) { Assert.notNull(dataSource, "You must supply a valid data source"); this.jdbcTemplate = new JdbcTemplate(dataSource); } } 

Ich verwende eine jdbcTemplate, um meine Verbindungen und Abfragen zu behandeln.

Nach stundenlangem Suchen, Austesten und Ausreißen meiner Haare stolperte ich schließlich über dieses kleine Juwel, das alle Antworten lieferte.

Ich hätte nie gedacht, dass so etwas das Problem ist, aber das Befolgen der oben beschriebenen Schritte funktionierte perfekt.

In meinem Dispatch-Servlet.xml hatte ich ursprünglich meinen Komponenten-Scan wie folgt deklariert:

  

Welches ist ein übergeordnetes Paket für alle meine Anwendungs-Beans. Wie im obigen Link beschrieben, überschrieb Spring meine transaktionalen Service-Beans aus der Datei applicationContext.xml mit den Service-Beans aus der Dispatcher-servlet.xml, die über die Transaktionen nicht wussten.

Alles, was ich getan habe, war, den obigen Komponenten-Scan zu unterbrechen, um nur die Ordner zu scannen, die nicht-transaktionale Beans enthielten.

      

Danach funktionierten meine Transaktionen genau wie erwartet und ich sah endlich Fußabdrücke der Transaktionen und des DataSourceTransactionManagers in meinen Logfiles. Dies behebt auch mein erstes Problem mit den automatischen Rollbacks in der database. Ich denke, es muss eng mit dem Mangel an Transaktionen verbunden gewesen sein.