1.共享鎖只用于表級,排他鎖用于行級。2.加了共享鎖的對象,可以繼續加共享鎖,不能再加排他鎖。加了排他鎖后,不能再加任何鎖。3.比如一個DML操作,就要對受影響的行加排他鎖,這樣就不允許再加別的鎖,也就是說別的會話不能修改這些行。同時為了避免在做這個DML操作的時候,有別的會話執行DDL,修改表的定義,所以要在表上加共享鎖,這樣就阻止了DDL的操作。4.當執行DDL操作時,就需要在全表上加排他鎖 為什么需要鎖(并發控制)?在多用戶環境中,在同一時間可能會有多個用戶更新相同的記錄,這會產生沖突。這就是著名的并發性問題。典型的沖突有: l 丟失更新:一個事務的更新覆蓋了其它事務的更新結果,就是所謂的更新丟失。例如:用戶A把值從6改為2,用戶B把值從2改為6,則用戶A丟失了他的更新。 l 臟讀:當一個事務讀取其它完成一半事務的記錄時,就會發生臟讀取。例如:用戶A,B看到的值都是6,用戶B把值改為2,用戶A讀到的值仍為6。為了解決這些并發帶來的問題。 我們需要引入并發控制機制。 并發控制機制悲觀鎖:假定會發生并發沖突,屏蔽一切可能違反數據完整性的操作。[1]樂觀鎖:假設不會發生并發沖突,只在提交操作時檢查是否違反數據完整性。[1] 樂觀鎖不能解決臟讀的問題。 樂觀鎖應用 1. 使用自增長的整數表示數據版本號。更新時檢查版本號是否一致,比如數據庫中數據版本為6,更新提交時version=6+1,使用該version值(=7)與數據庫version+1(=7)作比較,如果相等,則可以更新,如果不等則有可能其他程序已更新該記錄,所以返回錯誤。2. 使用時間戳來實現.注:對于以上兩種方式,Hibernate自帶實現方式:在使用樂觀鎖的字段前加annotation: @Version, Hibernate在更新時自動校驗該字段。 悲觀鎖應用 需要使用數據庫的鎖機制,比如SQL SERVER 的TABLOCKX(排它表鎖) 此選項被選中時,SQL Server 將在整個表上置排它鎖直至該命令或事務結束。這將防止其他進程讀取或修改表中的數據。SqlServer中使用Begin Transelect top 1 @TrainNo=T_NO from Train_ticket with (UPDLOCK) where S_Flag=0 update Train_ticket set T_Name=user, T_Time=getdate(), S_Flag=1 where T_NO=@TrainNocommit我們在查詢的時候使用了with (UPDLOCK)選項,在查詢記錄的時候我們就對記錄加上了更新鎖,表示我們即將對此記錄進行更新. 注意更新鎖和共享鎖是不沖突的,也就是其他用戶還可以查詢此表的內容,但是和更新鎖和排它鎖是沖突的.所以其他的更新用戶就會阻塞.結論在實際生產環境里邊,如果并發量不大且不允許臟讀,可以使用悲觀鎖解決并發問題;但如果系統的并發非常大的話,悲觀鎖定會帶來非常大的性能問題,所以我們就要選擇樂觀鎖定的方法.參考文檔[1]Concurrent Control http://en.wikipedia.org/wiki/Concurrency_control[2] Oracle的悲觀鎖和樂觀鎖http://space.itpub.net/12158104/viewspace-374745[3] timestamp應用——樂觀鎖和悲觀鎖【轉】http://hi.baidu.com/piaokes/blog/item/9b0c6854e4909050564e00b3.html