2

6 つのスクリプト/タスクがあります。それぞれが MySQL トランザクションを開始し、そのジョブを実行します。つまり、MySQL データベースからの SELECT/UPDATE/INSERT/DELETE を実行してから、ロールバックします。

したがって、データベースが特定の状態 S にある場合、1 つのタスクを起動します。タスクが終了すると、データベースは状態 S に戻ります。

スクリプトを順番に起動すると、すべて正常に動作します。

  • 状態 S の DB
  • タスク1
  • 状態 S の DB
  • タスク 2
  • 状態 S の DB
  • ...
  • ...
  • タスク 6
  • 状態 S の DB

しかし、マルチスレッド化してスクリプトを並行して起動することで、プロセスを高速化したいと考えています。

  • 状態 S の DB
  • 同時に6つのタスク
  • 状態 S の DB

一部のタスクはランダムに失敗し、次のエラーが発生することがあります。

SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction

よくわかりません。トランザクションはそのためのものだと思っていました。私が欠けているものはありますか?経験、アドバイス、手がかりは大歓迎です。

MySQL の構成は次のとおりです。

innodb_lock_wait_timeout = 500
transaction-isolation = SERIALIZABLE

各セッションの開始時に AUTOCOMMIT = 0 を追加します。

PS: データベースは、後で変更した REPEATABLE READ 分離レベルで構築および使用されました。

4

1 に答える 1

0

すべてのトランザクション/プロセスが、すべての場合に同じ ORDER BY を使用し、テーブル自体の同じ順序で (少なくとも反復可能な読み取り分離レベルで) 必要なすべてのデータ/テーブルに対して SELECT...FOR UPDATE を実行するようにすることで、デッドロックを防ぐことができます。 MySQL で)。

それとは別に、分離レベルとトランザクションはデッドロックを処理するためのものではありません。逆もまた同様であり、デッドロックが存在する理由です。デッドロックが発生した場合、データセットの状態に一貫性がない可能性が高くなります (これはより深刻な場合があります。そうでない場合は、トランザクションがまったく必要ない可能性があります)。

于 2012-07-10T12:24:38.760 に答える