Ich versuche, Spring-basierte Lösung für die Ausführung Batch von SQL-Abfragen auf MySQL 5.5-Server zu erstellen. Mit "Abfrage" meine ich jede SQL-Anweisung, die kompiliert, so dass der SQL-Batch-Job zum Beispiel mehrere CREATE TABLE, DELETE und dann INSERT-Anweisungen enthalten kann.Spring TransactionManager - Commit funktioniert nicht
Ich verwende Spring Batch für diesen Zweck.
Ich habe transactionManager
wie folgt konfiguriert.
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
und die dataSource
:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${batch.jdbc.driver}" />
<property name="url" value="${batch.jdbc.url}" />
<property name="username" value="${batch.jdbc.user}" />
<property name="password" value="${batch.jdbc.password}" />
<property name="maxIdle" value="10" />
<property name="maxActive" value="100" />
<property name="maxWait" value="10000" />
<property name="validationQuery" value="select 1" />
<property name="testOnBorrow" value="false" />
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="1200000" />
<property name="minEvictableIdleTimeMillis" value="1800000" />
<property name="numTestsPerEvictionRun" value="5" />
<property name="defaultAutoCommit" value="true" />
</bean>
Meine DAO Klasse hat die Methode konfiguriert mit
@Transactional(propagation = Propagation.REQUIRES_NEW)
und ich Schleife über eine Sammlung von SQL-Anweisungen, die Methode mit einzelnen SQL-Anweisung aufrufen eine Zeit. Die Verarbeitung innerhalb der Methode ist so einfach wie:
simpleJdbcTemplate.getJdbcOperations().execute(sql);
Ich erwartete, dass, wenn die DAO-Methode abgeschlossen ist, ich die Ergebnisse in der DB sehen würde. Es sieht jedoch so aus, als ob die Ausführung des Spring-Jobs erst dann abgeschlossen wird, wenn die Ergebnisse in der Datenbank verfügbar sind.
Ich habe versucht, das Commit in meinem DAO-Methode zu tun:
@Transactional(propagation = Propagation.REQUIRES_NEW)
private void executeSingleQuery(String sql) {
PlatformTransactionManager transactionManager = (PlatformTransactionManager)context.getBean("transactionManager");
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(Propagation.REQUIRED.ordinal());
TransactionStatus status = transactionManager.getTransaction(def);
try {
// execute your business logic here
log.info("about to execute SQL query[" + sql + "]");
simpleJdbcTemplate.getJdbcOperations().execute(sql);
} catch (Exception e) {
log.info("SQL query was not committed due to exception and was marked for rollback");
transactionManager.rollback(status);
}
transactionManager.commit(status);
if (transactionManager.getTransaction(null).isRollbackOnly()
&& transactionManager.getTransaction(null).isCompleted()) {
log.info("SQL query commited!");
} else {
log.info("SQL query was not committed due to: 1) the transaction has been marked for rollback " +
"2) the transaction has not completed for some reason");
}
log.info("the query has completed");
}
ich den Frühling Code debuggt und sah, dass die befehle ich Anruf von meinem DAO-Methode von TransactionTemplate ausgeführt wird (der Fluss erreicht die Linie this.transactionManager.commit(status);
und besteht ausnahmslos)
Ich würde mich über jeden Hinweis freuen, was getan werden sollte, damit die DAO-Methode bei jedem Aufruf festgeschrieben wird (Commit nach jeder ausgeführten SQL-Anweisung).
@Transaktionale Annotation kümmert sich um das Commit. In Ihrem Code brauchen Sie keinen Verweis auf den Transaktionsmanager und die Änderung wird explizit übernommen, nehme ich an. – ch4nd4n