SQL時間戳的使用

一直對時間戳這個概念比較模糊,相信有不少朋友也都會誤認爲:時間戳是一個時間字段,每次增長數據時,填入當前的時間值。其實這誤導了不少朋友。html

1.基本概念前端

時間戳:數據庫中自動生成的惟一二進制數字,與時間和日期無關的, 一般用做給錶行加版本戳的機制。存儲大小爲 8個字節。sql

每一個數據庫都有一個計數器,當對數據庫中包含 timestamp 列的表執行插入或更新操做時,該計數器值就會增長。該計數器是數據庫時間戳。這 能夠跟蹤數據庫內的相對時間,而不是時鐘相關聯的實際時間。一個表只能有一個 timestamp 列。每次修改或插入包含 timestamp 列的行 時,就會在 timestamp 列中插入增量數據庫時間戳值。這一屬性使 timestamp 列不適合做爲鍵使用,尤爲是不能做爲主鍵使用。對行的任 何更新都會更改 timestamp 值,從而更改鍵值。若是該列屬於主鍵,那麼舊的鍵值將無效,進而引用該舊值的外鍵也將再也不有效。若是該表在動態遊標 中引用,則全部更新均會更改遊標中行的位置。若是該列屬於索引鍵,則對數據行的全部更新還將致使索引更新。數據庫

使用某一行中的 timestamp 列能夠很容易地肯定該行中的任何值自上次讀取之後是否發生了更改。若是對行進行了更改,就會更新該時間戳值。若是沒有對行進行更改,則該時間戳值將與之前讀取該行時的時間戳值一致。若要返回數據庫的當前時間戳值,請使用 @@DBTS。服務器

 

 2.時間戳的做用併發

在控制併發時起到做用: 
用戶A/B同時打開某條記錄開始編輯,保存是能夠判斷時間戳,由於記錄每次被更新時,系統都會自動維護時間戳,因此若是保存時發現取出來的時間戳與數據庫中的時間戳不相等,說明在這個過程當中記錄被更新過,這樣的話能夠防止別人的更新被覆蓋。spa

3.時間戳的應用code

簡單說一下,timestamp 主要是記錄該行的最後修改時間戳,注意,這個時間戳是不能夠轉換爲時間的,只能標註該行修改了。

有 什麼用呢?一般是用在數據增量更新方面,好比說,我從該表複製數據到另一個表,可是若是我想只複製更新過的,那麼從最後一次更新的時候,記錄最大的 timestamp的值,而後在當前更新的時候,只要where條件找出大於最後一次更新的 timestamp 值的全部行。而後抽取到更新過的數據,進行復制到另一個服務器,這就是增量更新用到的。htm

4.在SQL中的應用例子blog

(微軟的建議 -- timestamp 語法已被取代,在 DDL 語句,請儘可能使用 rowversion 而不是 timestamp。將來的 Microsoft SQL Server 版本將移除這項功能

參見http://msdn.microsoft.com/zh-cn/library/ms182776.aspx)

rowversion 就是timestamp
丟失更新的解決方以下
丟失更新概念:當用戶同時修改一行數據,他們先讀取數據,放在前端進行修改,當修改後,再提交數據,這樣最後提交的數據會覆蓋先前提交的數據,
這樣就形成了丟失更新。
長話短說,介紹防止丟失更新的方法: 使用 rowversion 時間戳。
每次更新的時候,mssql都會自動的更新rowversion的值,若一行在讀前與更新前的值先後不一致,就說明有其餘的事務更新了此列,這樣就能夠不更新此列,
從而防止了丟失更新的狀況。
例子 :
先建立一個表:
declare table tmp(a varchar(10),b rowsversion)
insert into tmp(a) values( 'abc') 
 
事務A:(新建查詢   執行下列代碼)
declare @rv rowversion
select @rv=b from tmp where a='abc'
waitfor delay '00:00:05'  --休息5秒
update tmp set a='xyz' where b=@rv
go
 
事務B: (再新建查詢   執行下列代碼)
declare @rv rowversion
select @rv=b from tmp where a='abc'
update tmp set a='aaa' where b=@rv
go
 
事務A在執行完畢後會發現並無將'aaa'給抹去,這樣就防止了丟失更新的現象。
 
轉載:https://www.cnblogs.com/tianguook/p/3830234.html
相關文章
相關標籤/搜索