質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

1回答

11950閲覧

MySQLのデータ更新でInvalidOperationExceptionエラー

kirinsan

総合スコア13

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

1クリップ

投稿2019/02/12 07:51

編集2019/02/13 02:18
バージョン情報

MySQL 5.0.77
SQLServer2012
ASP.net(.NET Framework 4)

発生している問題・エラーメッセージ

SQLServerからMySQLへ、データ同期をとるために
複数テーブルに対して、

  1. MySQLデータのdelete
  2. SQLServerのselect
  3. MySQLへinsert(select件数分)

の3ステップによりデータの更新を行っていますが
運用して数年経った今、途中でエラーが発生するようになってしまいました。

System.InvalidOperationException: Connection must be valid and open to rollback transaction

このエラーに対する対処法を探しています。

同じデータで試しても開発環境では発生しない現象なので、環境設定に依存するのかと思い
MySQLにて「timeout」に関する設定を確認してみたのですが、いずれの環境でも以下のような設定になっており、差異が見つけられませんでした。

Variable_nameValue
connect_timeout10
delayed_insert_timeout300
innodb_lock_wait_timeout50
innodb_rollback_on_timeoutOFF
interactive_timeout28800
net_read_timeout30
net_write_timeout60
slave_net_timeout3600
table_lock_wait_timeout50
wait_timeout28800

よろしくお願いします。

=== 追記 ===
ソースは以下のように記述しています。

ASP.net

1Dim SE As New clsDbAccess 2Dim MySqlSE As New clsMySqlAccess 3 4'***** MySql接続設定開始 ***** 5MySqlSE.ConnectionString = "接続文字列" 6MySqlSE.CommandTimeout = CommandTimeout 7 8'### トランザクション 9MySqlSE.BeginTransaction() 10'***** MySql接続設定終了 ***** 11 12'### 接続コネクション設定(SqlServer) 13SE.ConnectionString = "接続文字列" 14SE.CommandTimeout = CommandTimeout 15 16'### トランザクション 17SE.BeginTransaction() 18 19' 20'SQLServerに対する更新処理 21'~~ 22' 23 24'SQLServer⇒MySQLへのデータ流し込み 25 26''deleteその1 27strSQL = "DELETE FROM tableA_MySQL WHERE ~" 28 29MySqlSE.CommandString = strSQL 30MySqlSE.ExecuteTSQL() 31 32''selectその1 33strSQL = "SELECT * FROM tableB_SQLServer WHERE ~" 34 35SE.TableName = "RESULT" 36SE.CommandString = strSQL 37SE.ExecuteSQL() 38 39Dim DT_TMP As DataTable = Nothing 40DT_TMP = SE.TableData.Tables(SE.TableName) 41 42For i = 0 To DT_TMP.Rows.Count - 1 43 ''insertその1 44 strSQL = " INSERT INTO tableC_MySQL (~) VALUES (~) " 45 46 MySqlSE.CommandString = strSQL 47 MySqlSE.ExecuteTSQL() 48Next 49 50''deleteその2 51strSQL = "DELETE FROM tableD_MySQL WHERE ~" 52 53MySqlSE.CommandString = strSQL 54MySqlSE.ExecuteTSQL() 55 56''selectその2 57strSQL = "SELECT * FROM tableE_SQLServer WHERE ~" 58 59SE.TableName = "RESULT" 60SE.CommandString = strSQL 61SE.ExecuteSQL() 62 63Dim DT_TMP As DataTable = Nothing 64DT_TMP = SE.TableData.Tables(SE.TableName) 65 66For i = 0 To DT_TMP.Rows.Count - 1 67 ''insertその2 68 strSQL = " INSERT INTO tableF_MySQL (~) VALUES (~) " 69 70 MySqlSE.CommandString = strSQL 71 MySqlSE.ExecuteTSQL() 72Next 73 74''deleteその3 75strSQL = "DELETE FROM tableG_MySQL WHERE ~" 76 77MySqlSE.CommandString = strSQL 78MySqlSE.ExecuteTSQL() 79 80''selectその3 81strSQL = "SELECT * FROM tableH_SQLServer WHERE ~" 82 83SE.TableName = "RESULT" 84SE.CommandString = strSQL 85SE.ExecuteSQL() 86 87Dim DT_TMP As DataTable = Nothing 88DT_TMP = SE.TableData.Tables(SE.TableName) 89 90For i = 0 To DT_TMP.Rows.Count - 1 91 ''insertその3 92 strSQL = " INSERT INTO tableI_MySQL (~) VALUES (~) " 93 94 MySqlSE.CommandString = strSQL 95 MySqlSE.ExecuteTSQL() 96Next 97 98'### コミット(SqlServer) 99SE.Commit() 100 101'### コミット(MySql) 102MySqlSE.Commit() 103 104 105 106 107'' クラス定義 108Public Class clsMySqlAccess 109 Public Function ExecuteTSQL() As Boolean 110 111 'トランザクションが開始されているかどうか 112 If _sqlTransaction Is Nothing Then 113 OpenConnection() 114 _sqlCommand = New MySqlCommand(_commandString, _sqlConnection) 115 _sqlCommand = _sqlConnection.CreateCommand 116 117 _sqlCommand.CommandTimeout = _commandTimeout 118 Else 119 _sqlCommand = New MySqlCommand(_commandString, _sqlConnection) 120 _sqlCommand.Transaction = _sqlTransaction 121 _sqlCommand.CommandTimeout = _commandTimeout 122 End If 123 124 _executeCount = _sqlCommand.ExecuteNonQuery() 125 126 If _sqlTransaction Is Nothing Then 127 CloseConnection() 128 End If 129 130 Return True 131 132 End Function 133End Class 134 135Public Class clsDbAccess 136 Public Function ExecuteSQL() As Boolean 137 138 Dim DS As New DataSet() 139 140 'トランザクションが開始されているかどうか 141 If _sqlTransaction Is Nothing Then 142 OpenConnection() 143 _sqlDataAdapter = New System.Data.SqlClient.SqlDataAdapter() 144 _sqlDataAdapter.SelectCommand = New System.Data.SqlClient.SqlCommand(_commandString, _sqlConnection) 145 _sqlDataAdapter.SelectCommand.CommandTimeout = _commandTimeout 146 Else 147 _sqlDataAdapter = New System.Data.SqlClient.SqlDataAdapter() 148 _sqlDataAdapter.SelectCommand = New System.Data.SqlClient.SqlCommand(_commandString, _sqlConnection) 149 _sqlDataAdapter.SelectCommand.Transaction = _sqlTransaction 150 _sqlDataAdapter.SelectCommand.CommandTimeout = _commandTimeout 151 End If 152 153 'DataSetにSelect結果を格納 154 _sqlDataAdapter.Fill(DS, _tableName) 155 _executeCount = DS.Tables(0).Rows.Count 156 157 _tableData = DS 158 159 If _sqlTransaction Is Nothing Then 160 CloseConnection() 161 End If 162 163 Return True 164 165 End Function 166End Class 167 168 169 170 171

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/02/12 08:44

ASP.NET のタグが付いてますが、ASP.NET Web アプリ特有の影響があるのでしょうか? もしそうであれば、そのあたりを詳しく書いていただかないと。(なければ ASP.NET のタグは外していただくようお願いします) エラーメッセージを見ると、1 と 3 はトランザクションに束ねてあるが、3 の時点で接続がクローズしてしまってロールバックできないというような問題に思えますが、そのあたりは詳しく調査されたのでしょうか? その結果は?
kirinsan

2019/02/12 11:31

申し訳ありませんが、ASP.NET特有の影響があるのかないのかも切り分けできていない状態です・・。 本文に追記しました通り、トランザクションは冒頭でかけて 最後まで処理がうまくいけばコミットとしていますが、ご質問はそういう意味ではないでしょうか? 今まで正常に動作していたのに、急に動かなくなったため混乱しております・・
退会済みユーザー

退会済みユーザー

2019/02/12 12:32

> 最後まで処理がうまくいけばコミットとしていますが、ご質問はそういう意味ではないでしょうか? 接続がクローズされてしまうのでコミットするところでエラーが出ているのでがないかと言ってます。
kirinsan

2019/02/12 13:08

意図してクローズは行っていませんし、インサートの前後にクローズに関わる条件分岐も入っていません。 逆に、処理完了後にも全くクローズしていないことに気が付きましたので、これはこれで修正の必要がありそうです・・
退会済みユーザー

退会済みユーザー

2019/02/12 22:42 編集

意図せずクローズされてしまうところが問題ではないかと言っているのですが。話を理解していただいているでしょうか。
退会済みユーザー

退会済みユーザー

2019/02/12 22:54

VB.NET, SQL Server などのタグを追加した方がよさどうです。ASP.NET では注目度が低そうなので。
kirinsan

2019/02/13 02:34

タグを変更いたしました。 意図せずクローズされているところがないか、デバッグで確認できるとよいのですが 開発環境では再現しないため検証できていない状態です。 環境次第で動作が異なるため、設定まわりによる原因なのではないかと思い、差異等を調べていましたが発見に至らずこちらで質問させていただいています。
guest

回答1

0

MySQLのバージョンが古いのが気になりますね。
現象を再現できる最低限のコードを提示した方が適切なコメントが付き易いです。
エラー・メッセージでググると、

System.InvalidOperationException: Connection must be valid and open to rollback transaction

InvalidOperationException during Transaction Rollback

[12 Aug 2009 17:29] Bugs System

A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

http://lists.mysql.com/commits/80702

パッチが提供されているようです。MySQLはオラクル社に回収されたからサポート契約が必要かも?

投稿2019/02/12 08:51

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kirinsan

2019/02/12 12:27

コードを追記いたしました。 確かに古すぎてMySQL Installerも存在していませんね・・今まで数年分の動作実績があることと 本番機のバージョンアップは気軽に行えないことより、バージョンアップは最終手段として考えていきたいと思います。 ありがとうございます。
Orlofsky

2019/02/12 21:03

コードが省略され過ぎていてわかりませんが、INSERT ... SELECT に直せればバグが回避できるかも?お使いのMySQLのバージョンで使えるかわかりません。 https://dev.mysql.com/doc/refman/5.6/ja/insert-select.html どちらにしてもバージョンが古過ぎて、機関銃で戦っている横で火縄銃を構えているようなのものですから、本当にシステムが止まってしまっても構わいならともかく、きちんと費用を確保してMySQLのバージョンアップをスケジュールに入れましょう。
kirinsan

2019/02/13 02:49

対応OSの問題もありますので、長い目で見てバージョンアップは対応予定ですが どんなに速くても数ヶ月先になってしまうと思いますので、直近で何とかする方法があればと思っています。 クエリ内容はあまり重要ではないと思って省略してしまいましたが、細かく記載することによって分かることもあるでしょうか? 同システムの別箇所にてINSERT ... SELECT が実装されている箇所がありますので、バージョン的には利用可能です。 INSERT ... SELECT に直せれば回避できるかもと判断された理由は、クエリ実行回数による制限やタイムアウト等、何らかの制限に引っ掛かったからなのではないかと考えられたということでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問