天天看點

SQL Server 2012 自動增長列,值跳躍問題

介紹

從 SQL Server 2012 版本開始, 當SQL Server 執行個體重新開機之後,表格的自動增長列的值會發生跳躍,而具體的跳躍值的大小是根據增長列的資料類型而定的。如果資料類型是 整型(int),那麼跳躍值為 1000;如果資料類型為 長整型(bigint),那麼跳躍值為 10000。從我們的項目來看,這種跳躍問題是不能被接受的,尤其是展示在用戶端的時候。這個奇怪的問題隻在 SQL Server 2012 及更高的版本中存在,SQL Server 2012之前版本不存在此問題。

背景

幾天前,我們QA組的同僚提出: 我們表格的自增列的值莫名奇妙的跳躍了 10000。也就是說,我們之前表格自增列的最後一個值為 2200,而現在新增一條記錄,自增列的值卻直接變成了 12200。在我們的業務邏輯中像這樣的情況是不允許展現在用戶端的,是以我們要解決此難題。

代碼使用

剛開始我們都很奇怪,這是怎麼發生的?我們通常不會手動向自增列插入任何值(向自增列手動插入值是可以的),自增列的值是由資料庫自行維護的。我們核心團隊的一位成員開始研究這個問題并找到了答案。現在,我想詳細講解下這個問題,以及我同僚找到的解決方案。

如何重制此bug

你需要安裝SQL Server 2012 然後建立一個測試資料庫。之後再建立一個帶有自增列的表格:

現在插入兩條資料:

檢視結果:

SQL Server 2012 自動增長列,值跳躍問題

此時結果和我們預期的一樣。 現在重新開機你的 SQL Server Service。重新開機SQL服務有多種方法,我們這裡通過 SQL Server 管理器來重新開機:

SQL Server 2012 自動增長列,值跳躍問題

重新開機之後,我們向剛才的表格再插入2條資料:

SQL Server 2012 自動增長列,值跳躍問題

現在你看到重新開機SQL Server 2012 之後的結果,它的自增列的值從1002開始了。 也就是跳躍了 1000。之前說過,如果我們自增列的資料類型是 長整型(bigint)的話,它的跳躍值就将會是 10000。

它真的是個BUG嗎?

微軟聲明這是一個功能而并非bug, 在很多場景下是很有用處的。 但是在我們的案例中,我們并不需要這樣的一個功能,因為這個自增資料是要展示給客戶的,客戶如果看到這樣跳躍性的資料,他們會感到很奇怪。并且跳躍值是根據你重新開機SQL Server的次數決定的。如果此資料不向客戶展示,或許還可以接受。是以此功能通常隻适合在内部使用。

解決方案

如果我們對微軟提供的這個 “功能” 不感興趣,我們可以通過兩種途徑來關閉它。

1. 使用序列 (Sequence)

2. 為SQL Server 注冊啟動參數 -t272

使用序列

首先,我們需要移除表格的自增列。然後建立一個不帶緩存功能的序列,根據此序列插入數值。 下面是示例代碼:

注冊啟動參數 -t272

打開SQL Server配置管理器。 選擇 SQL Server 2012 執行個體,右鍵, 選擇屬性菜單。在彈出的視窗中找到啟動參數,然後注冊 -t272。 完成之後重新開機下圖中的SQL Server(SQLSERVER2012), 之後進行bug重制的操作,驗證問題是否已解決。

SQL Server 2012 自動增長列,值跳躍問題

額外說明

如果在你的資料庫中有很多自增列的表,并且這些表都存在數值跳躍問題,那麼采用第2種方案更好一些。因為它非常簡單,并且作用域是伺服器級别的。采用第2種解決方案将會影響此服務執行個體上的所有資料庫。