Próbuję stworzyć oparte na źródle rozwiązanie do uruchamiania partii zapytań SQL na serwerze MySQL 5.5. Przez "zapytanie" rozumiem każdą instrukcję SQL, która się kompiluje, więc zadanie wsadowe SQL może zawierać na przykład kilka instrukcji CREATE TABLE, DELETE, a następnie INSERT.Spring TransactionManager - commit nie działa
Używam do tego celu Spring Batch.
Mam transactionManager
skonfigurowany w następujący sposób.
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
i 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>
Moja klasa DAO ma metodę skonfigurowany z
@Transactional(propagation = Propagation.REQUIRES_NEW)
i I pętli nad zbiór instrukcji SQL wywołanie metody z jednej instrukcji SQL czas. Przetwarzanie wewnątrz tej metody jest bardzo proste:
simpleJdbcTemplate.getJdbcOperations().execute(sql);
, że oczekuje się, że po zakończeniu sposób DAO ja patrz wyniki w PB. Jednak wydaje się, że tylko wtedy, gdy wykonanie zadania Spring zakończy się, wyniki stają się dostępne w DB.
Próbowałem zrobić to popełnić wewnątrz mojej metody DAO:
@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");
}
I debugowania kodu wiosną i zobaczył, że zobowiązują się nazywam od mojej metody DAO jest wykonywany przez TransactionTemplate (przepływ osiąga linię this.transactionManager.commit(status);
i przechodzi bez wyjątków)
Byłbym wdzięczny za wszelkie porady, co należy zrobić, aby metoda DAO była zatwierdzana przy każdym wywołaniu (zatwierdzenie po każdym poleceniu SQL, które wykonuje).
@ Adnotacja transakcyjna zajmuje się zatwierdzaniem. W twoim kodzie nie ma potrzeby odwoływania się do menedżera transakcji i zatwierdzania zmiany jawnie, jak przypuszczam. – ch4nd4n