使用 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)
我只是想检查一下,以防万一做错了什么,或者这是正常的数据库行为。
干杯。 贾斯。
I've started using TransactionScope to help with my unit tests, in order to put my test database back to it's previous state. Using this with SpecFlow, I have a base class like so:
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();
}
}
}
All of the above works, in that when I add records to the database, when I then query the tables after the tests have finished, those tables are empty. Great stuff, and very clever indeed!
My question relates to identity columns in these tables. What I've noticed is that, when I run my tests numerous times, the ID column of my test table increases by 1. I assumed that since the TransactionScope would rollback the changes, that the identity seed would also be rolled back.
Am I wrong in making this assumption - is this just how databases work? If that is the case, I could also run a SQL script before each of my scenarios that does this:
DBCC CHECKIDENT ('dbo.Items', reseed, 0)
I just wanted to check in case I was doing something wrong, or this is normal database behaviour.
Cheers.
Jas.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
标识列的种子值不会随 SQL Server 中事务的其余部分一起回滚。
这是设计使然,以便在整个事务持续时间内不必在计数器上放置独占锁以获取身份。
The seed value for an identity column does not get rolled back with the rest of a transaction in SQL Server.
This is by design so that an exclusive lock does not have to be placed on the counter for the identity for the entire duration of the transaction.
回滚后重新播种身份可能非常危险:如果另一个事务插入记录,就会发生身份冲突。
例如
这种情况尤其可能发生在您的
unit集成测试并行运行时(这是 NCrunch 中非常常见的行为)。经验法则:回滚后不要重新播种
另外,请参阅 marc_s 给 这个问题
Reseeding the identity after a rollback can be very dangerous: should another transaction insert a record, an identity collision would happen.
For example
This may happen especially if your
unitintegration tests run in parallel (this is a very common behavior with NCrunch).Rule of thumb: don't reseed after a rollback
Also, see the reply marc_s gave to this question