NOLOCK(不加鎖)
此選項被選中時,SQL Server 在讀取或修改數據時不加任何鎖。 在這種情況下,用戶有可能讀取到未完成事務(Uncommited Transaction)或回滾(Roll Back)中的數據, 即所謂的“臟數據”。
HOLDLOCK(保持鎖)
此選項被選中時,SQL Server 會將此共享鎖保持至整個事務結束,而不會在途中釋放。
UPDLOCK(修改鎖)
此選項被選中時,SQL Server 在讀取數據時使用修改鎖來代替共享鎖,並將此鎖保持至整個事務或命令結束。使用此選項能夠保證多個進程能同時讀取數據但只有該進程能修改數據。
TABLOCK(表鎖)
此選項被選中時,SQL Server 將在整個表上置共享鎖直至該命令結束。 這個選項保證其他進程只能讀取而不能修改數據。
PAGLOCK(頁鎖)
此選項為默認選項, 當被選中時,SQL Server 使用共享頁鎖。
TABLOCKX(排它表鎖)
此選項被選中時,SQL Server 將在整個表上置排它鎖直至該命令或事務結束。這將防止其他進程讀取或修改表中的數據。
HOLDLOCK 持有共享鎖,直到整個事務完成,應該在被鎖對象不需要時立即釋放,等於SERIALIZABLE事務隔離級別
NOLOCK 語句執行時不發出共享鎖,允許臟讀 ,等於 READ UNCOMMITTED事務隔離級別
PAGLOCK 在使用一個表鎖的地方用多個頁鎖
READPAST 讓sql server跳過任何鎖定行,執行事務,適用於READ UNCOMMITTED事務隔離級別只跳過RID鎖,不跳過頁,區域和表鎖
ROWLOCK 強制使用行鎖
TABLOCKX 強制使用獨占表級鎖,這個鎖在事務期間阻止任何其他事務使用這個表
UPLOCK 強制在讀表時使用更新而不用共享鎖
注意: 鎖定數據庫的一個表的區別
SELECT * FROM table WITH (HOLDLOCK) 其他事務可以讀取表,但不能更新刪除
SELECT * FROM table WITH (TABLOCKX) 其他事務不能讀取表,更新和刪
一個簡單的多並發生成單號問題就可以使用鎖來處理,比如:
begin tran
select MAX(BILL_NO) from sometalbe with(TABLOCKX)
...一些處理,如果生成新單號,保存數據
commit tran
使用這種事務一定要注意不要出現死鎖!
下面是引用博友的文章:
http://www.cnblogs.com/eric_ibm/archive/2012/08/22/lock.html
如何控制並發和控制死鎖(內含pb的處理要點)
鎖的概述
一. 為什么要引入鎖
多個用戶同時對數據庫的並發操作時會帶來以下數據不一致的問題:
丟失更新
A,B兩個用戶讀同一數據並進行修改,其中一個用戶的修改結果破壞了另一個修改的結果,比如訂票系統
臟讀
A用戶修改了數據,隨后B用戶又讀出該數據,但A用戶因為某些原因取消了對數據的修改,數據恢復原值,此時B得到的數據就與數據庫內的數據產生了不一致
不可重復讀
A用戶讀取數據,隨后B用戶讀出該數據並修改,此時A用戶再讀取數據時發現前后兩次的值不一致
並發控制的主要方法是封鎖,鎖就是在一段時間內禁止用戶做某些操作以避免產生數據不一致
二 鎖的分類
鎖的類別有兩種分法:
1. 從數據庫系統的角度來看:分為獨占鎖(即排它鎖),共享鎖和更新鎖
MS-SQL Server 使用以下資源鎖模式。
鎖模式 描述
共享 (S) 用於不更改或不更新數據的操作(只讀操作),如 SELECT 語句。
更新 (U) 用於可更新的資源中。防止當多個會話在讀取、鎖定以及隨后可能進行的資源更新時發生常見形式的死鎖。
排它 (X) 用於數據修改操作,例如 INSERT、UPDATE 或 DELETE。確保不會同時同一資源進行多重更新。
意向鎖 用於建立鎖的層次結構。意向鎖的類型為:意向共享 (IS)、意向排它 (IX) 以及與意向排它共享 (SIX)。
架構鎖 在執行依賴於表架構的操作時使用。架構鎖的類型為:架構修改 (Sch-M) 和架構穩定性 (Sch-S)。
大容量更新 (BU) 向表中大容量復制數據並指定了 TABLOCK 提示時使用。
共享鎖
共享 (S) 鎖允許並發事務讀取 (SELECT) 一個資源。資源上存在共享 (S) 鎖時,任何其它事務都不能修改數據。一旦已經讀取數據,便立即釋放資源上的共享 (S) 鎖,除非將事務隔離級別設置為可重復讀或更高級別,或者在事務生存周期內用鎖定提示保留共享 (S) 鎖。
更新鎖
更新 (U) 鎖可以防止通常形式的死鎖。一般更新模式由一個事務組成,此事務讀取記錄,獲取資源(頁或行)的共享 (S) 鎖,然后修改行,此操作要求鎖轉換為排它 (X) 鎖。如果兩個事務獲得了資源上的共享模式鎖,然后試圖同時更新數據,則一個事務嘗試將鎖轉換為排它 (X) 鎖。共享模式到排它鎖的轉換必須等待一段時間,因為一個事務的排它鎖與其它事務的共享模式鎖不兼容;發生鎖等待。第二個事務試圖獲取排它 (X) 鎖以進行更新。由於兩個事務都要轉換為排它 (X) 鎖,並且每個事務都等待另一個事務釋放共享模式鎖,因此發生死鎖。
若要避免這種潛在的死鎖問題,請使用更新 (U) 鎖。一次只有一個事務可以獲得資源的更新 (U) 鎖。如果事務修改資源,則更新 (U) 鎖轉換為排它 (X) 鎖。否則,鎖轉換為共享鎖。
排它鎖
排它 (X) 鎖可以防止並發事務對資源進行訪問。其它事務不能讀取或修改排它 (X) 鎖鎖定的數據。
意向鎖
意向鎖表示 SQL Server 需要在層次結構中的某些底層資源上獲取共享 (S) 鎖或排它 (X) 鎖。例如,放置在表級的共享意向鎖表示事務打算在表中的頁或行上放置共享 (S) 鎖。在表級設置意向鎖可防止另一個事務隨后在包含那一頁的表上獲取排它 (X) 鎖。意向鎖可以提高性能,因為 SQL Server 僅在表級檢查意向鎖來確定事務是否可以安全地獲取該表上的鎖。而無須檢查表中的每行或每頁上的鎖以確定事務是否可以鎖定整個表。
意向鎖包括意向共享 (IS)、意向排它 (IX) 以及與意向排它共享 (SIX)。
鎖模式 描述
意向共享 (IS) 通過在各資源上放置 S 鎖,表明事務的意向是讀取層次結構中的部分(而不是全部)底層資源。
意向排它 (IX) 通過在各資源上放置 X 鎖,表明事務的意向是修改層次結構中的部分(而不是全部)底層資源。IX 是 IS 的超集。
與意向排它共享 (SIX) 通過在各資源上放置 IX 鎖,表明事務的意向是讀取層次結構中的全部底層資源並修改部分(而不是全部)底層資源。允許頂層資源上的並發 IS 鎖。例如,表的 SIX 鎖在表上放置一個 SIX 鎖(允許並發 IS 鎖),在當前所修改頁上放置 IX 鎖(在已修改行上放置 X 鎖)。雖然每個資源在一段時間內只能有一個 SIX 鎖,以防止其它事務對資源進行更新,但是其它事務可以通過獲取表級的 IS 鎖來讀取層次結構中的底層資源。
獨占鎖:只允許進行鎖定操作的程序使用,其他任何對他的操作均不會被接受。執行數據更新命令時,SQL Server會自動使用獨占鎖。當對象上有其他鎖存在時,無法對其加獨占鎖。
共享鎖:共享鎖鎖定的資源可以被其他用戶讀取,但其他用戶無法修改它,在執行Select時,SQL Server會對對象加共享鎖。
更新鎖:當SQL Server准備更新數據時,它首先對數據對象作更新鎖鎖定,這樣數據將不能被修改,但可以讀取。等到SQL Server確定要進行更新數據操作時,他會自動將更新鎖換為獨占鎖,當對象上有其他鎖存在時,無法對其加更新鎖。
2. 從程序員的角度看:分為樂觀鎖和悲觀鎖。
樂觀鎖:完全依靠數據庫來管理鎖的工作。
悲觀鎖:程序員自己管理數據或對象上的鎖處理。
MS-SQLSERVER 使用鎖在多個同時在數據庫內執行修改的用戶間實現悲觀並發控制
三 鎖的粒度
鎖粒度是被封鎖目標的大小,封鎖粒度小則並發性高,但開銷大,封鎖粒度大則並發性低但開銷小
SQL Server支持的鎖粒度可以分為為行、頁、鍵、鍵范圍、索引、表或數據庫獲取鎖
資源 描述
RID 行標識符。用於單獨鎖定表中的一行。
鍵 索引中的行鎖。用於保護可串行事務中的鍵范圍。
頁 8 千字節 (KB) 的數據頁或索引頁。
擴展盤區 相鄰的八個數據頁或索引頁構成的一組。
表 包括所有數據和索引在內的整個表。
DB 數據庫。
四 鎖定時間的長短
鎖保持的時間長度為保護所請求級別上的資源所需的時間長度。
用於保護讀取操作的共享鎖的保持時間取決於事務隔離級別。采用 READ COMMITTED 的默認事務隔離級別時,只在讀取頁的期間內控制共享鎖。在掃描中,直到在掃描內的下一頁上獲取鎖時才釋放鎖。如果指定 HOLDLOCK 提示或者將事務隔離級別設置為 REPEATABLE READ 或 SERIALIZABLE,則直到事務結束才釋放鎖。
根據為游標設置的並發選項,游標可以獲取共享模式的滾動鎖以保護提取。當需要滾動鎖時,直到下一次提取或關閉游標(以先發生者為准)時才釋放滾動鎖。但是,如果指定 HOLDLOCK,則直到事務結束才釋放滾動鎖。
用於保護更新的排它鎖將直到事務結束才釋放。
如果一個連接試圖獲取一個鎖,而該鎖與另一個連接所控制的鎖沖突,則試圖獲取鎖的連接將一直阻塞到:
將沖突鎖釋放而且連接獲取了所請求的鎖。
連接的超時間隔已到期。默認情況下沒有超時間隔,但是一些應用程序設置超時間隔以防止無限期等待
五 SQL Server 中鎖的自定義
1 處理死鎖和設置死鎖優先級
死鎖就是多個用戶申請不同封鎖,由於申請者均擁有一部分封鎖權而又等待其他用戶擁有的部分封鎖而引起的無休止的等待
可以使用SET DEADLOCK_PRIORITY控制在發生死鎖情況時會話的反應方式。如果兩個進程都鎖定數據,並且直到其它進程釋放自己的鎖時,每個進程才能釋放自己的鎖,即發生死鎖情況。
2 處理超時和設置鎖超時持續時間。
@@LOCK_TIMEOUT 返回當前會話的當前鎖超時設置,單位為毫秒
SET LOCK_TIMEOUT 設置允許應用程序設置語句等待阻塞資源的最長時間。當語句等待的時間大於 LOCK_TIMEOUT 設置時,系統將自動取消阻塞的語句,並給應用程序返回"已超過了鎖請求超時時段"的 1222 號錯誤信息
示例
下例將鎖超時期限設置為 1,800 毫秒。
SET LOCK_TIMEOUT 1800
3) 設置事務隔離級別。
4 ) 對 SELECT、INSERT、UPDATE 和 DELETE 語句使用表級鎖定提示。
5) 配置索引的鎖定粒度
可以使用 sp_indexoption 系統存儲過程來設置用於索引的鎖定粒度
六 查看鎖的信息
1 執行 EXEC SP_LOCK 報告有關鎖的信息
2 查詢分析器中按Ctrl+2可以看到鎖的信息
七 使用注意事項
如何避免死鎖
1 使用事務時,盡量縮短事務的邏輯處理過程,及早提交或回滾事務;
2 設置死鎖超時參數為合理范圍,如:3分鍾-10分種;超過時間,自動放棄本次操作,避免進程懸掛;
3 優化程序,檢查並避免死鎖現象出現;
4 .對所有的腳本和SP都要仔細測試,在正是版本之前。
5 所有的SP都要有錯誤處理(通過@error)
6 一般不要修改SQL SERVER事務的默認級別。不推薦強行加鎖
解決問題 如何對行 表 數據庫加鎖
八 幾個有關鎖的問題
1 如何鎖一個表的某一行
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM table ROWLOCK WHERE id = 1
2 鎖定數據庫的一個表
SELECT * FROM table WITH (HOLDLOCK)
加鎖語句:
sybase:
update 表 set col1=col1 where 1=0 ;
MSSQL:
select col1 from 表 (tablockx) where 1=0 ;
oracle:
LOCK TABLE 表 IN EXCLUSIVE MODE ;
加鎖后其它人不可操作,直到加鎖用戶解鎖,用commit或rollback解鎖
幾個例子幫助大家加深印象
設table1(A,B,C)
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3
1)排它鎖
新建兩個連接
在第一個連接中執行以下語句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二個連接中執行以下語句
begin tran
select * from table1
where B='b2'
commit tran
若同時執行上述兩個語句,則select查詢必須等待update執行完畢才能執行即要等待30秒
2)共享鎖
在第一個連接中執行以下語句
begin tran
select * from table1 holdlock -holdlock人為加鎖
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二個連接中執行以下語句
begin tran
select A,C from table1
where B='b2'
update table1
set A='aa'
where B='b2'
commit tran
若同時執行上述兩個語句,則第二個連接中的select查詢可以執行
而update必須等待第一個事務釋放共享鎖轉為排它鎖后才能執行 即要等待30秒
3)死鎖
增設table2(D,E)
D E
d1 e1
d2 e2
在第一個連接中執行以下語句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30'
update table2
set D='d5'
where E='e1'
commit tran
在第二個連接中執行以下語句
begin tran
update table2
set D='d5'
where E='e1'
waitfor delay '00:00:10'
update table1
set A='aa'
where B='b2'
commit tran
同時執行,系統會檢測出死鎖,並中止進程
補充一點:
Sql Server2000支持的表級鎖定提示
HOLDLOCK 持有共享鎖,直到整個事務完成,應該在被鎖對象不需要時立即釋放,等於SERIALIZABLE事務隔離級別
NOLOCK 語句執行時不發出共享鎖,允許臟讀 ,等於 READ UNCOMMITTED事務隔離級別
PAGLOCK 在使用一個表鎖的地方用多個頁鎖
READPAST 讓sql server跳過任何鎖定行,執行事務,適用於READ UNCOMMITTED事務隔離級別只跳過RID鎖,不跳過頁,區域和表鎖
ROWLOCK 強制使用行鎖
TABLOCKX 強制使用獨占表級鎖,這個鎖在事務期間阻止任何其他事務使用這個表
UPLOCK 強制在讀表時使用更新而不用共享鎖
應用程序鎖:
應用程序鎖就是客戶端代碼生成的鎖,而不是sql server本身生成的鎖
處理應用程序鎖的兩個過程
sp_getapplock 鎖定應用程序資源
sp_releaseapplock 為應用程序資源解鎖
注意: 鎖定數據庫的一個表的區別
SELECT * FROM table WITH (HOLDLOCK) 其他事務可以讀取表,但不能更新刪除
SELECT * FROM table WITH (TABLOCKX) 其他事務不能讀取表,更新和刪除
1 如何鎖一個表的某一行
A 連接中執行
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
begin tran
select * from tablename with (rowlock) where id=3
waitfor delay '00:00:05'
commit tran
B連接中如果執行
update tablename set colname='10' where id=3 --則要等待5秒
update tablename set colname='10' where id<>3 --可立即執行
2 鎖定數據庫的一個表
SELECT * FROM table WITH (HOLDLOCK) 注意: 鎖定數據庫的一個表的區別SELECT * FROM table WITH (HOLDLOCK)
其他事務可以讀取表,但不能更新刪除
SELECT * FROM table WITH (TABLOCKX)
其他事務不能讀取表,更新和刪除
並發控制
並發能力是指多用戶在同一時間對相同數據同時訪問的能力。一般的關系型數據庫都具有並發控制的能力,但是這種並發功能也會對數據的一致性帶來危險。試想若有兩個用戶都試圖訪問某個銀行用戶的記錄並同時要求修改該用戶的存款余額時,情況將會怎樣呢?我們可以對PowerBuilder中的DataWindow進行設置來進行並發控制。所謂並發控制就是指在用戶數據修改的過程中保證該數據不被覆蓋或改變的方式,在下面的例子中我們將看到如何設置DataWindow來控制開發訪問。為了說明問題,我們舉這樣一個簡單的銀行系統中的例子,某用戶的存款狀況如右:
我們假設事情的經過是這樣的:公司的某員工在銀行前台取款2,000元,銀行出納查詢用戶的存款信息顯示銀行存款余額20,000元;正在這時,另一銀行帳戶轉帳支票支付該帳戶5,000元,機器查詢也得到當前用戶存款20,000元,這時銀行的出納員看到用戶存款超過了取款額,就支付了客戶2,000元並將用戶存款改為18,000元,然后銀行的另一名操作員根據支票,將匯入的5,000元加上,把用戶的余額改為25,000元,那么數據庫管理系統是否可以接受這些修改呢?
在DataWindows的設計中,我們選擇菜單Rows|Update…,會出現Specify Update Characteristics的設置窗口,在這個窗口中我們設置Update語句中Where子句的生成,以此來進行開發控制。在這里有三個選項,我們分別看一看在本例中這三個選項的結果:
(1)Key Columns:生成的Where子句中只比較表中的主鍵列的值與最初查詢時是否相同來確定要修改的記錄。在上述的例子中,轉帳支票的操作將覆蓋出納員作出的修改,這樣銀行損失兩千元。
(2)Key and Updateable Columns:生成的Where子句比較表中主鍵列和可修改列的值與最初查詢時否是相同。在上例中兩次查詢出的結果都是有兩萬余額,當第一個人修改余額時,余額仍是二萬元,所以修改成立,而支票轉帳操作時余額已不是二萬,所以該列不匹配,修改失敗。
(3)Key and Modified Columns:Where子句比較主鍵和將要修改的列,在本例中,結果與Key and Updateable Columns的選擇相同,因為余額已改變,不再與最初的查詢相同,因此仍然不能修改。
讓我們作另外一個假設,我們把銀行后台作支票轉帳操作改為凍結用戶存款,即把狀態字段的值改為凍結,而且事件發生的次序如下表,那么表中的次序4…前台出納的修改能不能成立呢:
1.Key Columns:Where子句只比較主鍵值,顯然出納員的修改是允許的。
2.Key and Updateable Columns:生成的Where子句包括比較所有可修改的列,因此出納修改時Statue字段為凍結與出納查詢時的tive不符,修改失敗,同時顯示錯誤信息。
3.Key and Modified Columns:Where子句的比較包括主鍵和要修改的列,由於本列中修改列仍為20,000元沒有變化,所以出納的修改可以成立。
在本例中,我們可以看到Key and Updateable Columns的選項最嚴格,可以避免出現狀態列發生改變時余額作修改的錯誤,但是這也會禁止我們作一些本當允許的並發修改,如出納修改存款余額,而業務員修改用戶的聯系地址等。因此我們應當根據實際情況,選擇適當的Update設置。
根據我們使用數據庫的不同,我們還有一些其他的控制並發訪問和修改的選擇方案,如對數據加鎖。鎖是一個用戶避免其他用戶對指定行作修改的操作。在結束一個事務如執行commit,rollback,disconnect等語句時自動將鎖釋放。如果您使用的DBMS支持鎖的操作,在Power-Builder的DataWindow設計時,Select語句可在from子句中加上with holdlock:即在data Window的SQL Window中,在表窗口的標題處點擊右鼠標,彈出菜單的最后一個選項即為Holdlock。選擇該項,生成的SQL語句將在re-trievel()函數執行后將所查詢的數據加鎖,以避免其他用戶的修改訪問,直至commit,rollback等事件發生后解鎖。這種方式帶來的問題是,當用戶查詢完數據后可能離開計算機長時間不用,這段時間內其他用戶均無法修改數據。此外有些DBMS如Sybase等不支持行級鎖,也就是說當你對某一行查詢時更多的行都被上了鎖,這就更增加了並發處理的局限性。另一個值得注意的問題是在多窗口應用中某一個窗口的事務提交將會導致使用一事務中其他數據窗口的查詢行解鎖,這時修改將可能發生錯誤。某些DBMS系統支持一個稱作"時間戳(timestamp)"的數據項來控制並發性。每張表中都有一個時間戳的數據列,當Insert語句或Update語句對數據行作修改時該列自動被修改為當前時間。當你要作修改時,where子句可檢查時間戳列在查詢時和修改時兩個值是否相符,以此來確保您作出的修改不會覆蓋別人的修改,因此這種確認方式與key and Updateable Columns選項相同。即使兩個用戶對同一行的不同列作修改,后一個修改者也將失敗。在常用的關系型數據庫中Sybase和Microsoft的SQL Server支持時間戳的使用。而在PowerBuilder中,不管用戶后台連接何種數據庫,只要表中帶有timestamp的列名且數據類型為datetime,PB將自動忽略Update characteristics的選項,而在where子句中生成主鍵和時間戳列的比較。
如果您所用的數據庫不支持時間戳但支持觸發器,您也可以在表中增加一列整數型的列。當有對表中某種記錄作修改時,該列自動加1。下列使用的是Watcom數據庫,對Shipper表增加Updcnt字段並作兩個觸發器,這樣任何用戶或進程試圖修改某行記錄時,該字段均可發生變化。
對INSERT觸發器的編寫如下:
DROP TRIGGER INS—SHIPPER’
CREATE TRIGGER SHIPPER BEFORE INSERT ON SHIPPER
REFERENCING NEW AS Newvalue
FOR EACH ROW
BEGIN
SET newvalue.UpdCnt=newvalue.UpdCnt+1;
END'
同理可編寫UPDATE觸發器。
在您的PowerBuilder應用之中,除表的主鍵外,必須再加上這一列作為檢測列加入Update語句中的Where子句中,這樣再作Update操作時,后台數據庫會比較修改時與用戶作Retrieve操作時數據是否相等,以確認是否能作修改。在DataWindows中在Specify Update Characteris-tics的對話框的右下角的Unique key column(s)中加上Updcnt一項,同時注意where clause中選擇Key columns,這樣PowerBuilder在構造where子句時就會認為Updcnt亦是表的主鍵,而成為檢測項。
當數據窗口的Update函數被調用后,觸發器將修改過記錄中的Updcnt列表為新值,為保證下一次修改能夠有效,您應當立即作Retrieve()以使DataWindow緩沖區中Updcnt的值與數據庫相同。顯然修改后立即查詢的代價要比其他任何一種並
發控制的代價要小得多。
不想倒也不覺得,可真的想想似乎好像也不是那么清楚,我的理解大概是這樣:
最嚴格的並發控制:
Key and Updateable Columns + Use Update
對主鍵和所有可更新列進行檢查:有任何一個列在提交時發生了變化即告失敗,即阻止事物之間修改同一數據。
直接更新方式:阻止事物內部對主鍵列進行任何交叉修改(邏輯正確也不行)。
最寬松的並發控制:
Key Columns + Use Delete then Insert
僅對主鍵列進行檢查:允許非主鍵列數據被不同事物同時修改。
刪除后插入方式:允許事物內部對主鍵列進行邏輯正確的交叉修改。
死鎖預防:
不同數據庫的鎖機制各不相同,但對應用程序來說,造成死鎖的最大可能就是:沒有養成對每個 COMMIT 的執行結果進行檢查的編碼習慣,導致提交出錯時未能及時 ROLLBACK 造成死鎖。
其實就是這么一個過程,在dw update時,他會先檢查你所定為key的幾列和retrieve時取出的來值是否相同,如果相同則update,不同則報
"row changed between retrieve and update"這個錯誤
如果出了這個錯你會看到在這個錯誤框里會有個update語句
update 表 set 你所設要更新的列 = :值
where 設定的key = 原來的值;
其實講了那么多,無非就是這么幾種情況:
1、在做報表時設置成:KEY AND MODIFIED COLUMNS && USE UPDATE
2、使用SQL語句: 加上LOCK或 RowLock.
3、記得UPDATE后要COMMIT或ROLLBACK。
4、運用FOCUS或存儲過程記得還要CLOSE。
一般來說,要簡單的話,記得這樣就可以了:
用DataWindow操作的話:
設置DW的Specify Update Characteristics為:
(3)Key and Modified Columns
這樣,只要你更新的列的值沒有變,則大家都可以成功,有效的防止了多用戶重疊更新的問題,相當安全,不必使用第二選項.
如果是使用SQL語句的話,就要使用事務,這樣就能確保你的修改是完整而且不被別人干擾的.而且不必使用上面各位朋友的復雜的方法,就這么簡單就可以:
假設有數值dec ldec_new = 2000
sqlca.autocommit=false //一定要設置為不自動提交
string ls_err
dec ldec_xxx
select column_xxx into :ldec_xxx from TABLE_yyy where id=keyvalue; //如果有必要查詢當前值的話.
if sqlca.sqlcode <0 then
ls_err=sqlca.sqlerrtext //先讀錯誤信息,然后立即ROLLBACK再提示,以免提示時用戶不確定,表還在鎖定中
rollback; //立即回滾,以免其它用戶等待.
messagebox("提示","數據庫發生以下錯誤:~n"+ls_err)
return
end if
update column_xxx=:ldec_new from table_yyy where id=keyvalue; //有必要的話再加 and column_xxx = :ldec_xxx
if sqlca.sqlcode <0 then
ls_err=sqlca.sqlerrtext //先讀錯誤信息,然后立即ROLLBACK再提示,以免提示時用戶不確定,表還在鎖定中
rollback; //立即回滾,以免其它用戶等待.
messagebox("提示","更新數據時發生以下錯誤:~n"+ls_err)
return
end if
commit using sqlca;
這樣就可以了,你在更新時,事務會鎖定其它的操作.