[Seasar-user:21745] Re: S2JDBC MySQL 2フェーズコミット

Koichi Kobayashi [E-MAIL ADDRESS DELETED]
2013年 10月 22日 (火) 19:58:57 JST


小林 (koichik) です。

> xaDataSource:org.seasar.extension.dbcp.impl.XADataSourceImpl

これは本物のXAConnectionではなく、本当に
2フェーズコミットを行うわけでもありません。
なので、

> この時、host2のテーブルはコミット?(データが挿入)されてしまいます。

ということは普通に起こり得ます。
実際は、DataSourceがトランザクションマネージャに
登録される順番に依存します。

・先に登録された方の接続先が障害になった場合は、
  後から登録された方のDataSourceはコミットされる
・後から登録された方の接続先が障害になった場合は、
  先に登録された方のDataSourceはロールバックされる

だったようなかすかな記憶が。。。

> xaDataSource:com.mysql.jdbc.jdbc2.optional.MysqlXADataSource

relaxAutoCommitがtrueなのはなぜでしょう?
ドキュメント眺めた限り、これをtrueにしなくては
いけないようだと、サーバ側がそもそもトランザクション
制御できない状況みたいですが。



On Tue, 22 Oct 2013 18:56:41 +0900, <kawashimat @ nexus21.co.jp> wrote:

> 川島といいます。お世話になります。
> 
> 2フェーズコミットのテストとして、
> host1(java バッチ)から、host2、host3のMySQLサーバーに
> S2JDBCを使用して、insertしようとしてます。
> 
> テストとしては、Eclipseを使用して、
> 0.Eclipse上でbreak pointをコミットの直前に設定
> 1.host2のテーブルをinsert
> 2.host2のテーブルをselectして確認
> 3.host3のテーブルをinsert
> 4.host3のテーブルをselectして確認
> 5.break pointで止まったことを確認
> 6.host3のMySQLを終了
> 7.Eclipseでコミットを実行
> 8.catchの処理の中でロールバックを実行
> 
> を行っています。
> 
> 
> ケース1
> jdbc.diconの設定
> xaDataSource:org.seasar.extension.dbcp.impl.XADataSourceImpl
> driverClassName:com.mysql.jdbc.Driver
> 
> 7.のところでexceptionが出力され、8.catchの処理へ
> 8.のロールバックでexceptionが出力され、トランザクションが無い旨
> のexceptionが出力される
> 
> この時、host2のテーブルはコミット?(データが挿入)されてしまいます。
> 
> MySQLサーバーのautocommitはoffにしています。
>  SELECT @ @autocommitの結果は「0」です。
> JDBCドライバのjarは、mysql-connector-java-5.1.23-bin.jarです。
> 
> 
> ケース2
> jdbc.diconの設定
> xaDataSource:com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
> 
> 7.のところで、exceptionが発生せず、正常にcommitされ、レコード
> がinsertされてしまいます。
> なので、commitの部分をrollbackに置き換え実験したところ、
> rollbackせずに、commitされてしまいます。
> 
> 
> 正しい設定方法が分からず困っています。
> どなたか、ご教授いただけないでしょうか。
> よろしくお願いします。
> 
> 
> 以下、設定ファイル、ソースです。
> 
> s2jdbc.dicon
> <components>
>     <include path="s2jdbcxp3.dicon"/>
>     <include path="s2jdbcxp4.dicon"/>
> </components>
> 
> s2jdbcxp3.dicon
> <components namespace="s2jdbcxp3">
> 	<include path="jdbcxp3.dicon"/>
> 	<include path="s2jdbc-internal.dicon"/>
> 	<component name="jdbcManagerXP3" class="org.seasar.extension.jdbc.
> manager.JdbcManagerImpl">
> 		<property name="maxRows">0</property>
> 		<property name="fetchSize">0</property>
> 		<property name="queryTimeout">0</property>
> 		<property name="dialect">mysqlDialect</property>
> 	</component>
> </components>
> 
> s2jdbcxp4.dicon
> <components namespace="s2jdbcxp4">
> 	<include path="jdbcxp4.dicon"/>
> 	<include path="s2jdbc-internal.dicon"/>
> 	<component name="jdbcManagerXP4" class="org.seasar.extension.jdbc.
> manager.JdbcManagerImpl">
> 		<property name="maxRows">0</property>
> 		<property name="fetchSize">0</property>
> 		<property name="queryTimeout">0</property>
> 		<property name="dialect">mysqlDialect</property>
> 	</component>
> </components>
> 
> jdbcxp3.dicon(ケース1)
> <components namespace="jdbc">
> 	<include path="jta.dicon"/>
> 
> 	<component name="xaDataSource"
> 		class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
> 		<property name="driverClassName">
> 			"com.mysql.jdbc.Driver"
> 		</property>
> 		<property name="URL">
> 		"jdbc:mysql://xp3/xxxxx?characterEncoding=utf8"
> 		</property>
> 		<property name="user">"user"</property>
> 		<property name="password">"password"</property>
> 	</component>
> 
> 	<component name="connectionPool"
> 		class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
> 		<property name="timeout">600</property>
> 		<property name="maxPoolSize">10</property>
> 		<property name="allowLocalTx">true</property>
> 		<destroyMethod name="close"/>
> 	</component>
> 
> 	<component name="DataSource"
> 		class="org.seasar.extension.dbcp.impl.DataSourceImpl"
> 	/>
> </components>
> 
> jdbcxp3.dicon(ケース2)
> <components namespace="jdbc">
> 	<include path="jta.dicon"/>
> 
> 	<component name="xaDataSource"
> 		class="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource">
> 		<property name="URL">
> 		"jdbc:mysql://xp3/xxxxx?characterEncoding=utf8"
> 		</property>
> 		<property name="user">"user"</property>
> 		<property name="password">"password"</property>
> 		<property name="relaxAutoCommit">true</property>
> 	</component>
> 
> 	<component name="connectionPool"
> 		class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
> 		<property name="timeout">600</property>
> 		<property name="maxPoolSize">10</property>
> 		<property name="allowLocalTx">true</property>
> 		<destroyMethod name="close"/>
> 	</component>
> </components>
> 
> jdbcxp4.dicon(ケース1)
> <components namespace="jdbc">
> 	<include path="jta.dicon"/>
> 
> 	<component name="xaDataSource"
> 		class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
> 		<property name="driverClassName">
> 			"com.mysql.jdbc.Driver"
> 		</property>
> 		<property name="URL">
> 		"jdbc:mysql://xp4/xxxxx?characterEncoding=utf8"
> 		</property>
> 		<property name="user">"user"</property>
> 		<property name="password">"password"</property>
> 	</component>
> 
> 	<component name="connectionPool"
> 		class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
> 		<property name="timeout">600</property>
> 		<property name="maxPoolSize">10</property>
> 		<property name="allowLocalTx">true</property>
> 		<destroyMethod name="close"/>
> 	</component>
> 
> 	<component name="DataSource"
> 		class="org.seasar.extension.dbcp.impl.DataSourceImpl"
> 	/>
> </components>
> 
> jdbcxp4.dicon(ケース2)
> <components namespace="jdbc">
> 	<include path="jta.dicon"/>
> 
> 	<component name="xaDataSource"
> 		class="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource">
> 		<property name="URL">
> 		"jdbc:mysql://xp4/xxxxx?characterEncoding=utf8"
> 		</property>
> 		<property name="user">"user"</property>
> 		<property name="password">"password"</property>
> 		<property name="relaxAutoCommit">true</property>
> 	</component>
> 
> 	<component name="connectionPool"
> 		class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
> 		<property name="timeout">600</property>
> 		<property name="maxPoolSize">10</property>
> 		<property name="allowLocalTx">true</property>
> 		<destroyMethod name="close"/>
> 	</component>
> </components>
> 
> 
> テスト用のjavaソース(パッケージは変えています)
> package kawa.batch;
> 
> import java.util.List;
> 
> import javax.transaction.NotSupportedException;
> import javax.transaction.SystemException;
> import javax.transaction.TransactionManager;
> 
> import kawa.entity.MClient;
> 
> import org.apache.log4j.Logger;
> import org.seasar.extension.jdbc.JdbcManager;
> import org.seasar.extension.jdbc.manager.JdbcManagerImpl;
> import org.seasar.extension.jta.TransactionManagerImpl;
> import org.seasar.framework.container.SingletonS2Container;
> import org.seasar.framework.container.factory.
> SingletonS2ContainerFactory;
> 
> public class Test2phaseCommit {
> 
> 	private Logger _log;
> 
> 	private TransactionManager transactionManager;
> 
> 	private JdbcManager jdbcManagerXP3;
> 	private JdbcManager jdbcManagerXP4;
> 
> 	public static void main(String[] args) throws NotSupportedException, 
> SystemException {
> 		Test2phaseCommit test = new Test2phaseCommit();
> 		test.init(args);
> 		test.exec(args);
> 
> 	}
> 
> 	private void init(String[] args){
> 		_log = Logger.getLogger(this.getClass());
> 		_log.debug("===== init =====");
> 
> 		SingletonS2ContainerFactory.init();
> 
> 		transactionManager = (TransactionManagerImpl)SingletonS2Container.
> getComponent("TransactionManager");
> 		jdbcManagerXP3 = (JdbcManagerImpl)SingletonS2Container.getComponent("
> jdbcManagerXP3");
> 		jdbcManagerXP4 = (JdbcManagerImpl)SingletonS2Container.getComponent("
> jdbcManagerXP4");
> 	}
> 
> 	private void exec(String[] args){
> 		_log.debug("===== exec =====");
> 
> 		insert();
> 
> 	}
> 
> 	private void insert(){
> 		_log.debug("===== insert =====");
> 
> 		MClient entity = new MClient();
> 		entity.clientName = "insert";
> 		entity.zip ="000-0000";
> 		entity.address = "有楽町1−1";
> 		entity.tel = "03-0000-0000";
> 
> 		try {
> 			transactionManager.begin();
> 			jdbcManagerXP3.insert(entity).execute();
> 			jdbcManagerXP4.insert(entity).execute();
> 
> 
> 
> 			List<MClient> lstXP3 = jdbcManagerXP3.selectBySql(MClient.class, "
> select * from m_client").getResultList();
> 			_log.info("===== XP3 start =====");
> 			for(MClient entXP3 : lstXP3){
> 				String str = new StringBuilder().append(" id:").append(entXP3.id)
> 						.append(" 取引先名:").append(entXP3.clientName)
> 						.append(" 郵便番号:").append(entXP3.zip)
> 						.append(" 住所:").append(entXP3.address)
> 						.append(" 電話番号:").append(entXP3.tel)
> 						.toString();
> 				_log.info(str);
> 			}
> 			_log.info("===== XP3 end =====");
> 
> 			List<MClient> lstXP4 = jdbcManagerXP4.selectBySql(MClient.class, "
> select * from m_client").getResultList();
> 			_log.info("===== XP4 start =====");
> 			for(MClient entXP4 : lstXP4){
> 				String str = new StringBuilder().append(" id:").append(entXP4.id)
> 						.append(" 取引先名:").append(entXP4.clientName)
> 						.append(" 郵便番号:").append(entXP4.zip)
> 						.append(" 住所:").append(entXP4.address)
> 						.append(" 電話番号:").append(entXP4.tel)
> 						.toString();
> 				_log.info(str);
> 			}
> 			_log.info("===== XP4 end =====");
> 
> 
> 
> 			transactionManager.rollback();
> //			transactionManager.commit();
> 		} catch (Exception e) {
> 			try {
> 				transactionManager.rollback();
> 			} catch (Exception e1) {
> 				e1.printStackTrace();
> 			}
> 		}
> 
> 	}
> 
> }
> 
> 
> 
> _______________________________________________
> Seasar-user mailing list
> Seasar-user @ ml.seasar.org
> https://ml.seasar.org/mailman/listinfo/seasar-user


-- 
{
  name: "Koichi Kobayashi",
  mail: "koichik @ improvement.jp",
  blog: "http://d.hatena.ne.jp/koichik/",
  twitter: "@koichik"
}



Seasar-user メーリングリストの案内