2014年2月25日火曜日

MyBatis 3 テーブル書込、トランザクション

src/main/webapp/WEB-INF/spring/root-context.xml へトランザクション設定追加
<bean id="transactionManager"    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource">
        <ref local="dataSource" />
    </property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>

サービスinterface
jp.s6131.sample.service.SampleService.java
package jp.s6131.sample.service;
・・・
public interface SampleService {
    ・・・
    public int insertList(List<Sample> sampleList);
}

サービス
jp.s6131.sample.service.impl.SampleServiceImpl.java
package jp.s6131.sample.service.impl;
・・・
@Service("sampleService")
public class SampleServiceImpl implements SampleService {
    @Autowired
    SampleMapper sampleMapper;
    ・・・
    @Override
    @Transactional
    public int insertList(List<Sample> sampleList) {
        int rtnTotal = 0;
        for (Sample sample : sampleList) {
            int rtn = sampleMapper.insert(sample);
            logger.debug("insert rtn = " + rtn);
            rtnTotal += rtn;
        }
        return rtnTotal;
    }
}

コントローラ
jp.s6131.sample.HomeController.java
@Autowired
SampleService sampleService;
・・・
List<Sample> sampleList = new ArrayList<Sample>();
for (int i = 0; i < 10; i++) {
    Sample sample = new Sample();
    sample.setCode("000000000" + (i + 1));
    sample.setName(String.format("Name%04d", i));
    sampleList.add(sample);
}
int rtn = sampleService.insertList(sampleList);
logger.debug("rtn = " + rtn);

実行ログ
DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@61fc1ea]
DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ==>  Preparing: insert into sample (id, code, name ) values (?, ?, ? )
DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ==> Parameters: null, 0000000001(String), java.io.StringReader@4b9bc91d(StringReader)
DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - <==    Updates: 1
DEBUG: jp.s6131.sample.service.impl.SampleServiceImpl - insert rtn = 1
DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@10cd263e]
DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ==>  Preparing: insert into sample (id, code, name ) values (?, ?, ? )
DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ==> Parameters: null, 0000000002(String), java.io.StringReader@25d4cfde(StringReader)
DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - <==    Updates: 1
DEBUG: jp.s6131.sample.service.impl.SampleServiceImpl - insert rtn = 1
DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@2c4f00de]
DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ==>  Preparing: insert into sample (id, code, name ) values (?, ?, ? )
DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ==> Parameters: null, 0000000003(String), java.io.StringReader@3bfa2596(StringReader)
DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - <==    Updates: 1
取得するコネクションが毎回違い、トランザクションが効いていない。
  • log4j.xml で Spring のログレベルを全て debug にしてもエラー等無く、原因が不明。
  • ネットで検索するとサービスが Spring に認識されていない事が原因らしいが、具体的な対応方法は不明。

対応した方法
servlet-context.xml でデフォルトで
<context:component-scan base-package="jp.s6131.sample>
となっていたのを
<context:component-scan base-package="jp.s6131.sample.controller>
とし、controller パッケージに HomeController.java を移動。

root-context.xml に
<context:component-scan base-package="jp.s6131.sample.service"/>
を追加し、サービスを具体的に検索対象に指定。

変更後の実行ログ
DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@1042ce9b]DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ==>  Preparing: insert into sample (id, code, name ) values (?, ?, ? ) DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ==> Parameters: null, 0000000001(String), java.io.StringReader@2fc64742(StringReader)DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - <==    Updates: 1DEBUG: jp.s6131.sample.service.impl.SampleServiceImpl - insert rtn = 1DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@1042ce9b]DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ==>  Preparing: insert into sample (id, code, name ) values (?, ?, ? ) DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ==> Parameters: null, 0000000002(String), java.io.StringReader@b3a0261(StringReader)DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - <==    Updates: 1DEBUG: jp.s6131.sample.service.impl.SampleServiceImpl - insert rtn = 1DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@1042ce9b]DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ==>  Preparing: insert into sample (id, code, name ) values (?, ?, ? ) DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - ==> Parameters: null, 0000000003(String), java.io.StringReader@1997ce1a(StringReader)DEBUG: jp.s6131.sample.mapper.SampleMapper.insert - <==    Updates: 1
コネクションが同じものを使用する様になり、トランザクションが効くようになった。


人気ブログランキングへ