Postgresql
驗證新訂單的可用性
我有一個來自 Web 界面的倉庫批發商的銷售、庫存和付款管理應用程序。特別是,當一個訂單被執行時,它必須創建一個對應於每個訂購了相應數量的產品的行。庫存可用性的驗證是在下訂單時完成的。
考慮以下兩種訂單驗證方式:
BEFORE INSERT
在 table 上使用觸發器,在驗證是否有足夠的庫存OrderLine
時執行 SELECT 。Product
- 做一個
SELECT ... FROM OrderLine JOIN Product WHERE quant < stock
。我的問題是:這兩種選擇中的哪一種更可取,為什麼/在什麼情況下?
我只看到你
SELECT
在兩種變體中都做 a 。如果您想確保您的銷售量不會超過您的庫存(庫存),您必須在下訂單的同一筆交易中減少您的庫存。對作業使用數據修改 CTE(Postgres 9.1 或更高版本):WITH u AS ( UPDATE product SET quant = quant - <put_order_quant_here> WHERE product_id = <order_prod_id> AND quant >= <put_order_quant_here> RETURNING product_id, <put_order_quant_here> AS quant ) INSERT INTO order_detail (order_id, product_id, quant) SELECT <put_order_id_here>, product_id, quant FROM u;
CTE 中的 僅在產品有足夠庫存的
UPDATE
情況下才返回值(並且它在行上具有寫鎖定)。在這種情況下,就在下訂單之前,在同一筆交易中減少了數量。將所有訂單詳細資訊放入一個事務中,如果其中任何一個失敗,
INSERT
則ROLLBACK
。可能的死鎖
這種情況很容易導致死鎖。假設您有兩個訂單同時進來,都想要產品 A 和 B。第一個訂單以 A 開頭,第二個訂單以 B 開頭。然後兩個交易相互阻止。每個都等待另一個完成。出現僵局。
在 PostgreSQL 中,事務會在被鎖停止時等待一段時間。根據您的設置
deadlock_timeout
(預設為 1 秒),將執行可能的死鎖檢查。一旦檢測到,就會中止一個事務並報告死鎖異常。另一個可以完成。哪一個很難預測。
有一個簡單的方法可以避免這種死鎖:始終將您
order_details
的順序保持一致。喜歡訂購的產品product_id
。這樣,上述情況永遠不會發生。