如何解决使用TransactionScope不会播种标识列
| 我已经开始使用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)
我只是想检查一下我做错了什么,或者这是正常的数据库行为。
干杯。
贾斯
解决方法
Identity列的种子值不会在SQL Server中与事务的其余部分一起回滚。
这是设计使然,因此不必在交易的整个持续时间内将独占锁放置在计数器上以获得身份。
, 回滚后重新提供身份非常危险:如果另一个事务插入一条记录,则会发生身份冲突。
例如
您开始交易
您在表t中插入一条记录:身份字段设置为10
约翰,在另一个并发客户端中,在表t中插入一条记录。由于第一笔交易没有提交也没有回滚,因此John \'s交易的身份字段设置为11
约翰进行交易。存储ID = 11的记录
您回滚交易
您将身份重新设置为先前的值,即9
您插入2个新记录。第二个将具有id = 11,随之发生身份冲突
尤其是如果您的单元集成测试并行运行时,可能会发生这种情况(这是NCrunch的非常常见的行为)。
经验法则:回滚后不要播种
另外,请参阅marc_s对这个问题的答复
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。