本文轉自:http://blog.sina.com.cn/s/blog_61cd89f60102e7di.html
在生產數據庫中,我們為了保證數據讀、寫的唯一性,經常會碰到下面五種鎖語句,區別在那?下面我們用實例說明一下:
1、FOR UPDATE
2、FOR UPDATE OF COLUMN
3、FOR UPDATE WAIT
4、FOR UPDATE NOTWAIT
5、FOR UPDATE NO WAIT SKIP LOCK
下面先來看看幾個例子:
1、SELECT * FROM EMP FOR UPDATE ; --鎖定表的所有行,只能讀不能寫
1 declare 2 cursor emp_cur 3 is 4 select * from emp for update ; --鎖定所有的行,只能讀不能寫 5 begin 6 for x in emp_cur loop 7 update emp set sal = 9999 where current of emp_cur ; 8 end loop ; 9 end ;
2、SELECT * FROM EMP WHERE DEPTNO = 10 FOR UPDATE ; --只鎖定DEPTNO = 10 的行
1 declare 2 cursor emp_cur 3 is 4 SELECT * FROM EMP WHERE DEPTNO = 10 FOR UPDATE ; --只鎖定DEPTNO = 10 的行 5 begin 6 for x in emp_cur loop 7 update emp set sal = 9999 where current of emp_cur ; 8 end loop ; 9 end ;
3、SELECT * FROM EMP E , DEPT D WHERE E.DEPTNO = D.DEPTNO FOR UPDATE --鎖定兩個表的所有記錄
4、SELECT * FROM EMP E , DEPT D WHERE E.DEPTNO = D.DEPTNO AND E.DEPTNO = 10 FOR UPDATE ; -- 鎖定兩個表中滿足條件的行
5、SELECT * FROM EMP E , DEPT D WHERE E.DEPTNO = D.DEPTNO AND E.DEPTNO = 10 FOR UPDATE OF E.DEPTNO ; --只會鎖定EMP表中滿足條件的行
可以看出來FOR UPDATE是把所有的表都鎖定,而FOR UPDATE OF 是根據OF后面的條件鎖定相應的表
第一點:
對於單表操作而言,FOR UPDATE 和 FOR UPDATE OF 是一樣的。不加條件是對全表的鎖定,加了條件是對行級別的鎖定。舉個栗子:
1、不加WHERE條件是對全表進行鎖定
SELECT * FROM EMP FOR UPDATE ; --對全表進行鎖定
2、加上WHERE條件是對行級別的鎖定
SELECT * FROM EMP WHERE DEPTNO = 10 FOR UPDATE ; --只對滿足條件的10部門進行鎖定
再次提醒FOR UPDATE 和 FOR UPDATE OF 對於單表操作是一樣的。
那么FOR UPDATE 和 FOR UPDATE OF 的區別到底在哪呢?在進行多表查詢時FOR UPDATE OF只鎖定列所在的表進行鎖定,而且是表級別的鎖定,FOR UPDATE是對多個表進行鎖定,不懂看例子:
1、SELECT * FROM EMP E ,DEPT D WHERE E.DEPTNO = D.DEPTNO AND E.DEPTNO = 10 FOR UPDATE OF E.DEPTNO ;
--只鎖定E.DEPTNO所在的表並且只鎖定DEPTNO = 10 的行
2、SELECT * FROM EMP E , DEPT D WHERE E.DEPTNO = D.DEPTNO AND E.DEPTNO = 10 FOR UPDATE ;
-- 鎖定多個表
1 和 2 的區別在於 , 1只鎖定表EMP 而 2 要鎖定EMP表和DEPT表 ,這才是二者真正的區別。 即 FOR UPDATE 是把所有的表都鎖上,而FOR UPDATE OF是根據相應的條件鎖定相應的表
第二點:關於NOWAIT(如果一定要使用FOR UPDATE,更建議使用NOWAIT)
1、當有LOCK沖突時會提示錯誤並結束STATEMENT而不是在那里等待(比如:要查的行已經被其它事務鎖了,當前的鎖事務與之沖突,加上nowait,當前的事務會結束會提示錯誤並立即結束 STATEMENT而不再等待).
2、WAIT 子句指定等待其他用戶釋放鎖的秒數,防止無限期的等待。
“使用FOR UPDATE WAIT”子句的優點如下:
1.防止無限期地等待被鎖定的行;
2.允許應用程序中對鎖的等待時間進行更多的控制。
3.對於交互式應用程序非常有用,因為這些用戶不能等待不確定
4.若使用了skip locked,則可以越過鎖定的行,不會報告由wait n 引發的‘資源忙’異常報告