1

MYSQLでテーブル名「test」を使用しています。これはトランザクションT1中にロックされ、20分で完了します。この20分以内に別のトランザクションT2によってこのテーブルを更新しているとき。例外が発生しています:-

11:58:38,584 ERROR [STDERR] java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
11:58:38,584 ERROR [STDERR]     at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2928)
11:58:38,584 ERROR [STDERR]     at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1571)
11:58:38,584 ERROR [STDERR]     at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1124)
11:58:38,584 ERROR [STDERR]     at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:676)

この例外を取得せずにこのトランザクションT2を実行するにはどうすればよいかという解決策を教えてください。

この例外を解決するために、mysqlデータベースのinnodb_lock_wait_timeoutの値を更新するのは正しいですか。この問題の有用な解決策が得られることを楽しみにしています。

4

2 に答える 2

7

innodb_lock_wait_timeout の値を更新することは、この問題を解決する正しい方法ではありません。まず、20 分に更新する必要があるように思えますが、これはばかげています。

innodb_lock_wait_timeout のデフォルトは 50 秒です。これは、T2 が T1 によってロックされたテーブルへのアクセスをあきらめる前に待機する時間の長さです (そして、表示されている例外が発生します)。

T2 トランザクションは何を行っていますか? 読み取りのみを実行している (つまり、テーブル "test" に書き込みを行っていない) 場合、データベースの分離レベルを "read uncommitted" に変更して、T2 がコミットされていないデータを読み取れるようにすることができます。ただし、IMO これは避けるべきハックです。

代わりに、設計/実装を検討する必要があります。トランザクションを開いて行ロックを 20 分間保持すると、マルチスレッド環境 (Web アプリケーションなど) で問題が発生します。

アーカイブ アクティビティ (20 分かかる) は 1 つのトランザクションで行う必要がありますか? この問題を解決する明白な方法は、すべてのステートメントの後にコミットするか、より適切なサイズのトランザクションに分割することです。

于 2012-10-04T11:57:41.573 に答える