ぺーぺーSEのブログ

備忘録・メモ用サイト。

Springによるトランザクション管理

Springによるトランザクション管理には以下の種類がある。

  • 宣言的トランザクション管理
    • Bean定義ベース
    • アノテーションベース
  • プログラミングによるトランザクション管理

Bean定義ベース

を使用して下記のようにBean定義する。

<!-- DataSourceの定義 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="${db.driver}" />
  <property name="url" value="${db.url}" />
  <property name="username" value="${db.username}" />
  <property name="password" value="${db.password}" />
</bean>

<aop:config>
    <aop:pointcut id="pointcut1" expression="execution(* exec*(..))" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1" />
</aop:config>

<!-- トランザクションマネージャの実装beanを定義 -->
<bean id="transactionManager"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<!-- transaction-managerにトランザクションマネージャの実装beanを設定 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
  <tx:attributes>
    <tx:method name="read*" read-only="true" />
    <tx:method name="*" />
  </tx:attributes>
</tx:advice>

トランザクションマネージャは「org.springframework.transaction.PlatformTransactionManager」を実装することで独自作成可能である。
Springでは下記の実装クラスがデフォルトで提供されている。

  • AbstractPlatformTransactionManager
    • すべてのトランザクションマネージャの抽象基底クラス。
  • DataSourceTransactionManager
    • 1つのDataSourceに対してトランザクション制御を行うトランザクションマネージャ。
  • JtaTransactionManager
    • JTAを使用するトランザクションマネージャ。
    • 二層コミット管理も可能?
  • HibernateTransactionManager
    • HibernateのSessionに対してトランザクション制御を行うトランザクションマネージャ。
  • JdoTransactionManager
    • JDOのPersistenceManagerに対してとトランザクション制御を行うトランザクションマネージャ。

DataSourceを利用したトランザクション制御を自作する場合、「org.springframework.jdbc.datasource.DataSourceUtils」を使用する必要がある。

アノテーションベース

下記のようにBean定義する。
Bean定義ベースに比べ、の定義が減っている。

<!-- DataSourceの定義 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="${db.driver}" />
  <property name="url" value="${db.url}" />
  <property name="username" value="${db.username}" />
  <property name="password" value="${db.password}" />
</bean>

<!-- トランザクションマネージャの実装beanを定義 -->
<bean id="transactionManager"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<tx:annotation-driven />

」が追加されているのがポイント。
あとはトランザクション境界としたいクラスやメソッドに「@Transactional」をつけるだけ。

プログラミングによるトランザクション管理

ソースコードの中でトランザクションの開始(begin-transaction)、コミット(commit)、ロールバック(rollback)を明記する方法。

import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

..(省略)..

@Autowired
private PlatformTransactionManager txManager;

public void execBLogic() {
  DefaultTransactionDefinition dtd = new DefaultTransactionDefinition();
  dtd.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
  dtd.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
  dtd.setTimeout(30);
  dtd.setReadOnly(false);
  TransactionStatus ts = txManager.getTransaction(dtd);
  try {
    // BLogic処理
  } catch (RuntimeException e) {
    txManager.rollback(ts);
    throw e;
  }
  txManager.commit(ts);
}

DefaultTransactionDefinitionをbean定義し、それをTransactionDefinitionで受けてインジェクションしてもよい。