我已经开始使用TransactionScope来帮助我进行单元测试,以便将我的测试数据库恢复到之前的状态。在SpecFlow中使用它,我有一个类似的基类:
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)
我只是想检查一下我做错了什么,或者这是正常的数据库行为。
干杯。 雅各
答案 0 :(得分:7)
标识列的种子值不会与SQL Server中的其余事务一起回滚。
这是设计使得在整个交易期间不必在柜台上放置专有锁定的身份。
答案 1 :(得分:2)
回滚后重新标记身份可能非常危险:如果另一个事务插入记录,则会发生身份冲突。
例如
如果您的单元集成测试并行运行,这可能会发生(这是NCrunch的一种非常常见的行为)。
经验法则:在回滚后不要重新设定
另请参阅marc_s给this question的回复