2017-11-13 3 views
0

InnoDBで株価表のデータの整合性を維持する方法はありますか?これには、テーブルロックとトランザクションの両方を使用する必要がありますか?私はいくつかの良い例を見つけようとしましたが、よく知られているopensource eコマースソフトウェアでさえテーブルロック/トランザクションを実装していません。コードの下で動作するでしょうか?本当にテーブル全体をロックする必要があるのですか?あるいは、販売された製品の行だけをロックする方法はありますか?あるいは誰かが良い例を持っていますか?在庫テーブルのテーブルおよび/または取引をロックしますか?

CREATE TABLE `stock` (
    `product_id` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_unicode_ci', 
    `quantity` INT(10) UNSIGNED NOT NULL DEFAULT '0', 
    PRIMARY KEY (`product_id`) 
) 
COLLATE='utf8mb4_unicode_ci' 
ENGINE=InnoDB; 

LOCK TABLES stock WRITE; 
START TRANSACTION; 
SET autocommit = 0; 
UPDATE stock SET quantity = quantity - 4 WHERE product_id = 'PRODUCT_1' AND quantity >= 4; 
UPDATE stock SET quantity = quantity - 2 WHERE product_id = 'PRODUCT_2' AND quantity >= 2; 
UPDATE stock SET quantity = quantity - 5 WHERE product_id = 'PRODUCT_3' AND quantity >= 5; 
COMMIT or ROLLBACK; 

すべてのUPDATEクエリは1つの影響を受けた行を持っている場合、COMMIT、あなたは同じコードを実行していることを確認同時クライアントを作成する場合を除き、それ以外の場合は

答えて

0

をロールバックテーブル・ロックを行うことが必要ではないはずありません同時更新を実行します。あなたのアップデートのそれぞれが別々の行のサブセットで動作しているので、私はそれが重要であるとは確信していません。

いずれの場合でも、トランザクションの開始後にautocommit = 0を設定する必要はありません。トランザクションを暗黙的に開始すると、COMMITを使用する(または暗黙のコミットを引き起こす文がある)まで、コミットしないことを意味します。

各更新が少なくとも1行変更されていることを確認する必要があるという点を除いて、3つの更新を1つの更新にまとめることさえできます。

0

「影響を受けた行」はテストされていません。失敗、デッドロック、タイムアウトなどがテストされます。それぞれ1行でなければ失敗するには、rows_affectedを取得し、 "1"をテストしてからROLLBACKをテストする必要があります。

また、

COMMIT or ROLLBACK 

ニーズは、 "その後、COMMIT他ROLLBACK ...場合" とします。これはアプリケーション言語で行うのが最適です。

関連する問題