[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で質問しましょう!
似たような質問が見つかりました
- Java インスタンス ダウンキャストについて以下の解釈であっているか教えて欲しいです。 サブクラスをスーパー 1 2022/03/27 18:53
- Access(アクセス) Access DAOのExecuteメソッドのオプション(RecordsetOptionEnum)に 1 2022/09/19 07:34
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- MySQL 参考書に従って入力したつもりでしたが、最後はエラーがでました。 1 2022/09/28 03:45
- MySQL 何にかが違うから エラーなんでしょうね! 2 2022/09/18 05:28
- SQL Server PCが悪くなって新しいPCにSSMSのデータを移すよう頼まれたけど移し方が分からない 1 2023/05/18 16:54
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- MySQL MySQLのテーブル作成でハイフン - は使用できないのでしょうか? 2 2022/10/21 16:50
- その他(パソコン・スマホ・電化製品) 送信メールフォルダーの中身が突然なくなった 2 2022/11/13 18:55
- 英語 【 論・表 英訳 】 問題 A:次の月曜日に東京を訪れる予定なんだ。会えない? B:運がいい。私は1 2 2022/07/24 21:55
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
DB2で SQL1032N start databas...
-
クラスタリングとレプリケーシ...
-
SQLServer2005上の別DBからテ...
-
oracleのメモリ使用量が97%ほど...
-
AWSのRDSを無料枠で使用してお...
-
インスタンス、ノード、ターゲ...
-
AWS初学者です。 AWSの学習を終...
-
SIDとSERVICE_NAMEの違いとは?
-
ORA-12170のエラーについて
-
Oracle11g SQLPlusログインにつ...
-
「ORA-12637」エラーでORACLEに...
-
突然オラクルへ接続できなくな...
-
OraOps10.dllのエラーについて
-
住所コード11桁の住所データ...
-
Real Playerで動画が見れない
-
正しいSQLなのに「ORA-00936: ...
-
Windows Storeを使わずに付箋を...
-
.NET Frameworkがコントロール...
-
AIRの音声化について
-
SQL 全角半角混在の文字列から...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
DB2で SQL1032N start databas...
-
oracleのメモリ使用量が97%ほど...
-
AWS初学者です。 AWSの学習を終...
-
SQLServer2005上の別DBからテ...
-
クラスタリングとレプリケーシ...
-
SQLServer 2008のインスタンス...
-
インスタンス、ノード、ターゲ...
-
SQLSERVER データインポート
-
OracleDBConsoleorclのサービス...
-
SQL Server 2005 の インスタ...
-
Windows2000でのOSシャットダウ...
-
インスタンスの再作成について
-
SQLサーバーへの接続について
-
SQLサーバーの停止。
-
SQLServer2005 リンクサーバー...
-
SQL Server 2005(2008)とVB.net...
-
Oracleのセッションの強制タイ...
-
SQLserver2005のデータベースミ...
-
データベースをオープンできない
-
SIDとSERVICE_NAMEの違いとは?
おすすめ情報