通常,這是一種糟糕的方法,會導致顯着的性能,縮放和支持問題。我會重新考慮這個設計。
如果你想這樣做,你需要強制你的事務序列化。您可以使用主鍵爲room_id
和room_count
值的單獨表格,或者可以將該列添加到room
。您需要通過select for update
鎖定room_id
的行。然後,您將更新room_count
並將其用於您的insert
。鎖定將在您的事務提交時釋放。
但是,如果您這樣做,則涉及相同room_id
的每個其他交易都將被阻止。如果您的交易時間相對較短,假設您沒有太多的用戶與同一個房間一起工作,那麼這可能並不可怕。隨着用戶數量和交易時間的增加,問題變得更加困難。如果交易涉及多個房間,則您需要每筆交易以相同的順序處理它們(例如,以room_id
爲例),以避免潛在的死鎖。如果你打算做的事情不僅僅是這張桌子,事情會變得更加複雜。
我寧願使用一個序列,然後在查詢中生成順序值。例如
SELECT room_id,
rank() over (partition by room_id order by sequence_column) your_num_order
FROM your_table
或者你可以使用sequence_column
的初始插件,並有後臺作業定期(每天是常見的),並在批處理分配num_order
交易完成後。在before insert
觸發
Create or replace function inc_room_cnt(p_room_id NUMBER) return number as
PRAGMA autonomous_transaction;
v_cnt NUMBER;
begin
update room_count set cnt = cnt +1 where room_id = p_room_id returning cnt into v_cnt;
-- insert new room if not yet exists
if SQL%ROWCOUNT = 0 then
v_cnt := 1;
insert into room_count values (p_room_id, v_cnt);
end if;
commit;
return v_cnt;
end;
/
可以撥打inc_room_cnt
設置:
非常感謝。但這個解決方案對我來說似乎很複雜 – Khoa
@Khoa,解決方案非常複雜,因爲隱藏在您需求背後的陷阱非常複雜。 –