MySQL 5.5 サーバーで SQL クエリのバッチを実行するための Spring ベースのソリューションを作成しようとしています。「クエリ」とは、コンパイルする任意の SQL ステートメントを意味するため、SQL バッチ ジョブには、たとえば、複数の CREATE TABLE、DELETE、および INSERT ステートメントを含めることができます。
この目的のためにSpring Batchを使用しています。
以下のようにtransactionManager
構成しました。
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
そして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>
私のDAOクラスには、で構成されたメソッドがあります
@Transactional(propagation = Propagation.REQUIRES_NEW)
そして、一度に 1 つの SQL ステートメントでメソッドを呼び出す SQL ステートメントのコレクションをループします。メソッド内の処理は次のように単純です。
simpleJdbcTemplate.getJdbcOperations().execute(sql);
DAO メソッドが完了すると、結果が DB に表示されることを期待していました。ただし、Spring ジョブの実行が完了したときにのみ、結果が DB で利用可能になるようです。
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");
}
Spring コードをデバッグしたところ、DAO メソッドから呼び出したコミットが TransactionTemplate によって実行されることがわかりました (フローは行に到達し、this.transactionManager.commit(status);
例外なく通過します) 。
DAOメソッドをすべての呼び出しでコミットするために何をすべきかアドバイスをいただければ幸いです(実行するすべてのSQLステートメントの後にコミットします)。