這種資料類型表現自動產生的位元,確保這些數在資料庫中是唯一的。timestamp 一般用作給表行加版本戳的機制。儲存大小為 8 位元組。
一個表只能有一個 timestamp 列。每次插入或更新包含 timestamp 列的行時,timestamp 列中的值均會更新。這一屬性使 timestamp 列不適合作為鍵使用,尤其是不能作為主鍵使用。對行的任何更新都會更改 timestamp 值,從而更改索引值。如果該列屬於主鍵,那麼舊的索引值將無效,進而引用該舊值的外鍵也將不再有效。如果該表在動態資料指標中引用,則所有更新均會更改遊標中行的位置。如果該列屬於索引鍵,則對資料行的所有更新還將導致索引更新。
不可為空白的 timestamp 列在語義上等價於 binary(8) 列。可為空白的 timestamp 列在語義上等價於 varbinary(8) 列。
在實際的多使用者並發訪問的生產環境裡邊,我們經常要儘可能的保持資料的一致性。而其中最典型的例子就是我們從表裡邊讀取資料,檢查驗證後對資料進行修改,然後寫回到資料庫中。在讀取和寫入的過程中,如果在多使用者並發的環境裡邊,其他使用者已經把你要修改的資料
進行了修改是非常有可能發生的情況,這樣就造成了資料的不一致性。解決這樣的辦法,SQL SERVER提出了樂觀鎖定和悲觀鎖定的概念,下邊我以一個執行個體來說明如何使用樂觀鎖定和悲觀鎖定來解決這樣的問題。
/* 建立測試表:Train_ticket,代表一個真實的火車票庫,供使用者註冊.使用者要從裡邊購買一個未使用的火車票,也就是S_Flag=0的票,給使用者註冊:更新T_Name,T_Time,S_Flag欄位. 如果出現兩個使用者同時更新一張票的情況,是不能容忍的,也就是我們所說的資料不一致行。*/
create table Train_ticket(T_NO varchar(20),T_Name varchar(20),S_Flag bit,T_Time datetime)
悲觀鎖定解決方案
Begin Tran
select 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=@TrainNo
commit
注意其中的區別了嗎?with(updlock),是的,我們在查詢的時候使用了with (UPDLOCK)選項,在查詢記錄的時候我們就對記錄加上了更新鎖定,表示我們即將對次記錄進行更新.注意更新鎖定和共用鎖定是不衝突的,也就是其他使用者還可以查詢此表的內容,但是和更新鎖定和排它鎖是衝突的.所以其他的更新使用者就會阻塞.如果我們在另外一個視窗執行此代碼,同樣不加waifor delay子句.兩邊執行完畢後,我們發現成功的註冊了兩張火車票.可能我們已經發現了悲觀鎖定的缺點:當一個使用者進行更新的事務的時候,其他更新使用者必須排隊等待,即使那個使用者更新的不是同一條記錄.
樂觀鎖定解決方案
-- 首先我們在Train_ticket表裡邊加上一列T_TimeStamp 列,該列是varbinary(8)類型.但是在更新的時候這個值會自動成長.
alter table Train_ticket add T_TimeStamp timestamp not null
-- 取得號和原始的時間戳記值
select top 1 @TrainNo=T_No,
@timestamp=T_TimeStamp
from Train_ticket
where S_Flag=0
-- 延遲50秒,類比並發訪問.
waitfor delay '000:00:50'
-- 購買票,但是要比較時間戳記是否發生了變化.如果沒有發生變化.更新成功.如果發生變化,更新失敗.
update Train_ticket
set T_Name=user,
T_Time=getdate(),
S_Flag=1
where T_No = @TrainNo and F_TimeStamp = @timestamp
set @rowcount=@@rowcount
if @rowcount=1
begin
print 'Successful!'
commit
end
else if @rowcount=0
begin
if exists(select 1 from Train_ticket where T_No = @TrainNo)
begin
print 'The ticket was already buyed.'
rollback tran
end
else
begin
print 'This ticket doesn't exist!'
rollback tran
end
end
上邊我詳細介紹了樂觀鎖定和悲觀鎖定的使用方法,在實際生產環境裡邊,如果並發量不大,我們完全可以使用悲觀鎖定的方法,因為這種方法使用起來非常方便和簡單.但是如果系統的並發非常大的話,悲觀鎖定會帶來非常大的效能問題,所以我們就要選擇樂觀鎖定的方法.