
[OSのVER]:Windows Server 2003 SP2 (x64)
[SQLServerのVER]:2005 Standard Edition SP3
お世話になります。トーシロです。
以下の現象で解決方法がわからず悩んでいます。
解決方法がございましたご教授頂けますでしょうか。
よろしくお願い致します。
状況:
・インスタンスAとインスタンスBがあります。
・インスタンスAにリンクサーバーとしてインスタンスBを登録してあります。
・インスタンスA.テーブルaにJDBC経由でデータをインサートします。
・インスタンスA.テーブルaインサートトリガーXにて、
インスタンスB.テーブルbにデータをインサートします。
・トリガーXはT-SQLで記述しています。
・トリガーX内にBEGIN TRANSACTION、COMMIT TRANSACTIONを記述しています。
(記述しないとBEGINとCOMMITの対応数が違うという内容のエラーとなりました。)
・JDBC経由でのデータのインサートは一連のトランザクション内となります。
JDBC実装内容:
1.setAutoCommit(false)
↓
2.executeUpdate()で複数回のインサート
↓
3.commit()
↓
4.例外発生時はrollback()
・ユーザはインスタンスA、インスタンスB共に「sa」を使用しています。
・MSDTCは「開始」となっています。
上記状況で以下の操作をします。
1件目をインスタンスA.テーブルaにインサート→正常終了するデータをトリガーXにてインスタンスB.テーブルbにインサートします。
2件目をインスタンスA.テーブルaにインサート→制約違反が起きるデータをトリガーXにてインスタンスB.テーブルbにインサートします。
この際にエラーが発生しますが、インスタンスB.テーブルbの1件目のデータがロールバックされず、コミットされてしまいます。
インスタンスB.テーブルbの1件目のデータがコミットされないようにするには、どのような実装が必要になるのでしょうか。
(同一インスタンス内のテーブルではロールバックされます。)
以下実行時エラーです。
2パターンがランダムに出力されました。
パターン1:
Error Code:1206
SQL State:S000118
com.microsoft.sqlserver.jdbc.SQLServerException: Microsoft 分散トランザクション コーディネータ (MS DTC) により、この分散トランザクションがキャンセルされました。
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(Unknown Source)
at com.microsoft.sqlserver.jdbc.IOBuffer.processPackets(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.sendExecute(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.doExecuteUpdate(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(Unknown Source)
at TestInsert.write(TestInsert.java:86)
at TestInsert.main(TestInsert.java:43)
パターン2:
Error Code:3971
SQL State:S0001
com.microsoft.sqlserver.jdbc.SQLServerException: サーバーはトランザクションを再開できませんでした。説明: 3400000002。
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(Unknown Source)
at com.microsoft.sqlserver.jdbc.IOBuffer.processPackets(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectionCommand(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendRollback(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.rollback(Unknown Source)
at TestInsert.write(TestInsert.java:96)
at TestInsert.main(TestInsert.java:43)
以上、よろしくお願い致します。
No.1ベストアンサー
- 回答日時:
Javaは使っていないのですが、リンクサーバに関する限り同様の環境で試してみても、そのような事象は確認できませんでした。
したがってあくまで推測の域ですが、ポイントはリンクサーバ側というよりもJDBC側ではないでしょうか?
とりあえず、以下のあたりをお勧めします。
・SQL Server単体で実行して、本当にロールバックされないか試してみる。
BEGIN TRY
BEGIN TRAN
INSERT INTO テーブルa values (...) -- 正常終了するもの
INSERT INTO テーブルa values (...) -- 制約違反が生じるもの
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
END CATCH
・以下のページをチェックして、JDBC経由でのMSDTCが正しく機能しているか確認する。
http://msdn.microsoft.com/ja-jp/library/ms378931 …
この回答への補足
申し訳ありません。再度検証したところ、動作結果が違いました。
以下のとおりです。
インサートするデータの中身:
1件目:正常データ
2件目:制約違反が起きるデータ
3件目:正常データ
このデータのパターンでJDBC経由とT-SQL単体での確認を行いました。
JDBC経由での結果:
3件目が登録されてしまう
2件目でエラーとなり2件目までロールバックされるが、
3件目が別トランザクションとして処理されている?
T-SQLでの結果:
3件目が登録されない
2件目でエラーとなりロールバックされ、
処理が終了していると考えられる
(T-SQLの記述内容)
BEGIN TRY
BEGIN TRAN
INSERT INTO テーブルa values (...) -- 正常終了するもの
INSERT INTO テーブルa values (...) -- 制約違反が生じるもの
INSERT INTO テーブルa values (...) -- 正常終了するもの
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
END CATCH
ですのでjamshid6さんのご指摘のとおり、
JDBCの処理方法の問題ということがわかりました。
ありがとうございます&失礼いたしました。
ご回答大変ありがとうございます。
・SQL Server単体で実行して、本当にロールバックされないか試してみる。
試してみたところ、同様にロールバックされませんでした。
・以下のページをチェックして、JDBC経由でのMSDTCが正しく機能しているか確認する。
MSDTCの「XA トランザクションを有効にする」のチェックが入っていませんでしたので、チェックを入れMSDTCを再起動した後、インスタンスAとB共にサービスを再起動しました。
そして確認として、JDBCを経由せずに直接インサート文を発行し、試してみましたところ、依然とロールバックされない状況です。
残念ながらJAVA側のソースを書き換えるという手段が取れない状況でして、諦めてSQL CLRのTransactionScopeを使用した実装に書き直そうかと思っています。
※SQL CLRのTransactionScopeを使用した実装ではロールバックされることを確認しました。
大変ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
DB2で SQL1032N start databas...
-
SQLサーバーの停止。
-
「ORA-12637」エラーでORACLEに...
-
SIDとSERVICE_NAMEの違いとは?
-
事務コンのデータ移行
-
ORAー12560:TNS:protocol adap...
-
ObjectBrowserでエクスポート
-
ORA-12170のエラーについて
-
シムシティ4 DX をCDなしで遊び...
-
Oracle10g・・ODBCで接続できない
-
倒産した18禁ゲーム会社のパ...
-
SQL 全角半角混在の文字列から...
-
データソース名および指定され...
-
異なる文字コードの環境にイン...
-
SAIを違うPCで使いたい
-
Oracle11g SQLPlusログインにつ...
-
sqlplus / as sysdba で接続不可
-
突然オラクルへ接続できなくな...
-
instantclient cse接続ができない
-
ODBC接続によるパスワード回避
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
DB2で SQL1032N start databas...
-
oracleのメモリ使用量が97%ほど...
-
SQLServer2005上の別DBからテ...
-
E-RモデリングとUML
-
クラスタリングとレプリケーシ...
-
OracleDBConsoleorclのサービス...
-
SIDってなんですか?
-
インスタンス、ノード、ターゲ...
-
SQLServer2005 リンクサーバー...
-
MS SQL2005での接続エラー
-
SQL Server 2005(2008)とVB.net...
-
Windows2000でのOSシャットダウ...
-
Oracle 8i のアンストール方法
-
SQLSERVER データインポート
-
db2_installコマンドについて
-
SQLServer2000と7.0の共存
-
SQLサーバーへの接続について
-
SQL Server のシャットダウンの...
-
Sql Server 2005 でlocalにサー...
-
SQLサーバーの停止。
おすすめ情報