次のことを行うストアド プロシージャが必要です。
テーブルをロックします
その中の値をチェックします
その値に基づいて同じテーブルを更新します
テーブルのロックを解除します
1~4の間でエラーが発生した場合、テーブルのロックは解除されますか? または、何らかの方法でエラーをキャプチャする必要がありますか? (どうやって?)
これを行うより良い方法はありますか?
次のことを行うストアド プロシージャが必要です。
テーブルをロックします
その中の値をチェックします
その値に基づいて同じテーブルを更新します
テーブルのロックを解除します
1~4の間でエラーが発生した場合、テーブルのロックは解除されますか? または、何らかの方法でエラーをキャプチャする必要がありますか? (どうやって?)
これを行うより良い方法はありますか?
MySQL のストアド プロシージャ内でテーブルをロックすることはできません。
ストアド ルーチンで許可されていない SQL ステートメント
ストアド ルーチンに任意の SQL ステートメントを含めることはできません。次のステートメントは許可されていません。
ロック ステートメント
LOCK TABLES
とUNLOCK TABLES
.— http://dev.mysql.com/doc/refman/5.6/en/stored-program-restrictions.html
InnoDB を使用している場合は、ロック読み取りを使用して目的の行をロックすることで目的を達成できますSELECT ... FOR UPDATE
。エラーが発生してトランザクションをロールバックすると、行は自動的にロック解除されます。
これについては、この最近の回答で詳細に書きました。質問には競合する挿入を回避することが含まれていましたが、必要な行が既に存在するかどうか、または存在するかどうかに関係なく、基本的な概念は同じです。
try-catch ブロックでトランザクションを使用することを検討しましたか? これを参照してください:
BEGIN TRAN
SAVE TRAN S1 -- Savepoint so any rollbacks will only affect this transaction
BEGIN TRY
/* Do your work in here */
END TRY
BEGIN CATCH
ROLLBACK TRAN S1 -- rollback just this transaction
SET @ErrorMessage = ERROR_MESSAGE()
SET @Severity = ERROR_SEVERITY()
SET @State = ERROR_STATE()
RAISERROR(@ErrorMessage, @Severity, @State) -- re-throw error if needed
END CATCH