2011-06-06 37 views
3

我使用TransactionScope來幫助我的單元測試開始,爲了把我的測試數據庫恢復到之前的狀態。與SpecFlow利用這一點,我有一個基類,像這樣:使用的TransactionScope不補種標識列

public class TransactionScopedFeature 
{ 
    private TransactionScope Scope { get; set; } 

    [BeforeScenario] 
    public void BaseSetup() 
    { 
     this.Scope = new TransactionScope(TransactionScopeOption.RequiresNew); 
    } 

    [AfterScenario] 
    public void BaseCleanup() 
    { 
     if (this.Scope != null) 
     { 
      this.Scope.Dispose(); 
     } 
    } 
} 

以上所有的作品,在那個時候我記錄添加到數據庫中,當我再查詢表測試完成後,這些表是空的。偉大的東西,確實非常聰明!

我的問題涉及到這些表中標識列。我注意到的是,當我多次運行我的測試時,我的測試表的ID列增加1.我認爲由於TransactionScope會回滾這些更改,所以標識種子也會回滾。

我錯在做這樣的假設 - 這是數據庫是如何工作的?如果是這樣的話,我也可以我的每一個場景,做這個之前,運行SQL腳本:

DBCC CHECKIDENT ('dbo.Items', reseed, 0)

我只是想萬一我做錯了什麼檢查,或這是正常的數據庫行爲。

乾杯。 Jas。

+0

回覆也許它只是一個錯字,但單元測試不應該打的數據庫。您可能在談論整合(或端到端)測試。 – 2012-04-11 08:55:51

回答

7

標識列的種子值不會被回滾與事務的SQL Server中的其餘部分。

這是由設計,使得排它鎖並沒有被放置在櫃檯上的同一性爲交易的整個持續時間。

+0

好,夠公平的。正如我前面提到的,我可以輕鬆運行'DBCC'命令。爲此歡呼。 – 2011-06-06 21:32:06

2

補播回滾後的身份是非常危險的:應該另一事務插入一條記錄,身份碰撞會發生。

例如

  1. 你開始交易
  2. 您插入表t中的記載:標識字段設置爲10
  3. 約翰,在另一個併發客戶端插入表t的記錄。由於第一筆交易沒有提交也沒有回滾,約翰的交易對於身份字段設置爲11
  4. 約翰提交了他的交易。使用id = 11的記錄存儲
  5. 你回滾您的交易
  6. 您補種的身份到以前的值,也就是9
  7. 您插入2個新的記錄。第二個將有ID = 11,用consiquent身份衝突

這種情況可能發生,特別是如果你的 單位 集成測試並行運行(這是NCrunch一個很常見的行爲)。

經驗法則:回滾後不補種

而且,看到marc_s給了this question