即使事务回滚,SQL标识(自动编号)也会增加
我有一个.net事务与SQL插入到MS SQL 2005数据库。 该表具有标识主键。
当事务发生错误时,会调用Rollback()。 行插入被正确回滚,但是当我下一次向表中插入数据时,身份就像从未发生回滚一样递增。 所以基本上在身份序列中存在差距。 有没有办法让Rollback()方法回收失踪的身份?
我不是以正确的方式接近这个吗?
如果你仔细想想,自动递增数字不应该是事务性的。 如果其他交易不得不等待自动编号被使用或“回滚”,则它们将被使用自动编号的现有交易阻塞。 例如,考虑下面的表代码,使用ID列的自动编号字段:
User 1 ------------ begin transaction insert into A ... insert into B ... update C ... insert into D ... commit User 2 ----------- begin transaction insert into A ... insert into B ... commit
如果用户2的事务在用户1之后开始毫秒,那么他们插入到表A中将不得不等待用户1的整个事务才能完成,看是否使用了从第一次插入到A的自动编号。
这是一个function,而不是一个错误。 我build议使用另一个scheme来生成自动编号,如果你需要它们紧密顺序。
如果你依靠你的身份价值无缝,那么是的 – 你做错了。 代理键的整个意义在于没有商业意义 。
而且,不,没有办法改变这种行为(缩小自己的自动增量,并且承受阻塞其他插入的性能后果)。
如果您也DELETE
了一行,则会在序列中出现空白。
序列必须是唯一的,但不要求是连续的。 他们单调增长的事实只是一种执行而已。
据我所知,插入行索赔自动编号和回滚该数字是失去了好。 如果你依赖于正在sorting的自动编号,你可能要考虑你正在使用的方法。
我不认为有任何要求自动编号的按键顺序。 事实上,我不认为他们可以被要求是:
- 交易一开始接入
- 事务b启动并插入
-
交易中止
你会得到一个洞。 没有关系。
所有其他海报谁不说担心,你应该得到的差距是正确的。 如果这个数字具有商业意义,而且这个意义不会有差距,那么就不要使用一个标识列。
仅供参考,如果出于任何原因您想要消除这些差距,大多数数据库都有办法将自动编号重新设置为您所select的编号。 这是一个痛苦的屁股,如果你发现自己需要定期做,你绝对不应该使用自动编号/身份领域,如上所述。 但是这里是在SQL服务器中执行的代码:
DBCC CHECKIDENT('Product',RESEED,0)
这将产品表设置为从1开始(尽pipe如果表中有logging,它显然会跳过已经采用的ID值)。其他RDBMS供应商有其自己的语法,但效果大致相同,所以在系统帮助文件或互联网上查找“种子标识”或“重新设置自动编号”。
再次说明:这是针对特殊的场合,而不是经常使用。 不要把它存储在存储过程中,让我们都来到那里。
Muhan试图在执行这个交易的许多同时连接的情况下考虑它,而不是一次一个。 有些会失败,有些会成功。 您希望SQL Server专注于在新请求进入时运行,而不是维护无间隙标识列。 海事组织(价值观的差距)绝对是不值得花时间的东西。
序列实现使用自主事务。 在Oracle中,自治事务曾经是dbms的内部事务,但现在已经暴露给自己使用(而且经常被错误地使用)
PRAGMA AUTONOMOUS_TRANSACTION;'
- 组中的哪个单选button被选中?
- 如何在C#中只设置DateTimevariables的时间部分
- 新的netstandardapp和netcoreapp TFM之间有什么区别?
- 奇怪的铸造行为。 无法将对象(int)强制转换为long
- 最有效的方法来检查DBNull,然后分配给一个variables?
- AppDomain和MarshalByRefObject的生命时间:如何避免RemotingException?
- 相当于C#的“使用”关键字在PowerShell中?
- 如果我在使用声明结束之前返回,会发生什么情况? 这个configuration会被调用吗?
- 如何编组multidimensional array