如果使用得當,游標是非常強大的數據庫控制結構,利用游標可以遍歷和處理游標査詢(或操作)定義的結果集中的數據。在要指定一個數據集進行遍歷或遍歷處理數據集中的行時,游標非常有用。數據集中的數據項可以更新、刪除、修改或讀取,也可以被其他進程査看。游標的真正強大之處在于可以作為程序設計語言的擴展,因為許多過程和面向對象的程序設計語言都沒有提供內置的管理關系數據庫的數據集的功能。在高速事務處理系統中,在SEL,ECP游標中使用 FOR UPDATE從句可能造成問題,甚至造成死鎖。
在許多數據庫中,一旦打開了具有 FOR UPDATE從句的游標,那么該語句查詢到的行都會被鎖住,直到會話中執行到了提交或回退語句為止。 COMMIT語句會保存修改, ROLLBACK語句會取消所有的修改。執行到這兩個語句中的任何一個,與數據庫中的行相關的鎖都會被釋放掉。此外,執行了提交或回退語句后,你就會失去在游標中的位置,不能再從游標中提取記錄了。
暫停一下,你能發現游標SELECT OR UPDAI8E至少可能會造成兩個問題嗎?第一個問題是,游標會在執行操作時一直保留數據庫行的鎖。在許多情況下,這樣可能都是有用的,甚至在少數情況下,這樣做是不可避免的,或者是最佳方案。但是,在執行某些操作時,這些鎖會使其他事務一直阻塞或等待。如果這些操作很復雜或需要花費一些時間,那么就會堆起許多待處理的事務。如果恰好這些事務是游標執行 SELECT FOR UPDATE操作要執行的,那么我們可能就會創建了一個等待隊列,而隊列的處理時間是用戶不能接受的。在Web環境中,讓缺乏耐心的用戶等待漫長的響應會造成他們發起更多的請求,而這后來的請求有可能會完成得更快。結果是災難性的,我們的系統會停機,因為待處理的請求堆在數據庫端,最終會造成Web服務器占用了所有TCP端口,從而停止響應用戶。
第二個問題前面提示過,是第一個問題造成的。必須等到之前的鎖清除了,后面的游標才能對當前鎖住的一行或多行加鎖。注意,這些鎖可能不是游標加的,它可以是用戶加的顯式鎖,也可以是 RDBMS加加的隱式鎖。數據庫中的鎖越多,事務堆積的可能性越大,雖然有些鎖是必需的。長期保留的鎖會造成對經常請求的數據的響應時間變慢。有些數據庫,如 Oracle,有選用的天鍵子NOWA 可以把控制權釋放
給進程,用于執行其他的工作或在再次取得鎖之前等待。但是,如果游標必須處理某些同時發生的客戶請求,那么對用戶來說,最終結果是一樣的,就是客戶端請求都需要等待很久才能得到響應。
注意,有些網站制作數據庫默認會在游標中使用 FOR UPDATE從句。事實上,ANSI的SQL標準指示,任何游標都要默認使用 FOR UPDATE從句,除非它在 DECLARE語句中使用了 FOR READ ONLY從句。開發人員和DBA應該參考他們的數據庫文檔,看看如何開發鎖最少的游標。
本文地址:http://murenxiang.com.cn//article/3499.html