1、for update nowait 與 for update 的目的:
鎖定表的所有行,排斥其他針對這個表的寫操作。確保只有當前事務對指定表進行寫操作。
例子:
for update
1 select * from TTable1 for update 鎖定表的所有行,只能讀不能寫
2 select * from TTable1 where pkid = 1 for update 只鎖定pkid=1的行
3 select * from Table1 a join Table2 b on a.pkid=b.pkid where a.pkid = 10 for update 鎖定兩個表的中滿足條件的行
4 select * from Table1 a join Table2 b on a.pkid=b.pkid where a.pkid = 10 for update of a.pkid 只鎖定Table1中滿足條件的行
for update 是把所有的表都鎖點 for update of 根據of 后表的條件鎖定相對應的表列。
for update nowait
1 select * from TTable1 for update nowait鎖定表的所有行,只能讀不能寫
2 select * from TTable1 where pkid = 1 for update nowait只鎖定pkid=1的行
3 select * from Table1 a join Table2 b on a.pkid=b.pkid where a.pkid = 10 for update nowait鎖定兩個表的中滿足條件的行
4 select * from Table1 a join Table2 b on a.pkid=b.pkid where a.pkid = 10 for update of a.pkid nowait只鎖定Table1中滿足條件的行
for update nowait是把所有的表都鎖點 for update of ... nowait根據of 后表的條件鎖定相對應的表列。
2、現在大家看到加nowait和不加nowait關鍵字好像沒有區別,那么區別在哪呢?
for update nowait和 for update 都會對所查詢到得結果集進行加鎖,所不同的是,如果另外一個線程正在修改結果集中的數據:
①for update會進行資源等待,必須等到查詢結束后(commit)后,才允許另一個線程進行修改。
②for update nowait 不會進行資源等待,只要發現結果集中有些數據被加鎖,立刻返回 “ORA-00054錯誤,內容是資源正忙, 但指定以 NOWAIT 方式獲取資源”。
3、SELECT...FOR UPDATE 語句的語法如下:
SELECT ... FOR UPDATE [OF column_list][WAIT n|NOWAIT][SKIP LOCKED];
其中:
OF 子句用于指定即將更新的列,即鎖定行上的特定列。
WAIT 子句指定等待其他用戶釋放鎖的秒數,防止無限期的等待。
課外小知識:
“使用FOR UPDATE WAIT”子句的優點如下:
1防止無限期地等待被鎖定的行。
2允許應用程序中對鎖的等待時間進行更多的控制。
3對于交互式應用程序非常有用,因為這些用戶不能等待不確定 。
4 若使用了skip locked,則可以越過鎖定的行,不會報告由wait n 引發的‘資源忙’異常報告。
4、實際運用
業務場景如下:同一應用分布在兩臺服務器上,兩個應用上有同一個定時任務,兩個定時任務會操作同一個資源,為了防止一個定時任務進行的時候另一個定時任務也會獲取到這個資源,所以
利用行鎖對同一資源進行判斷。
①首先創建一個表LOCK_BUS_TAB_FOR_TASK,在表中創建兩個字段,如下圖:
②在程序開始時進行判斷,如果這個鎖已被持,程序直接結束,不執行定時任務。
核心代碼
調用代碼
這就避免了對同一資源的重復操作。