我遇到一个奇怪的问题。我有一个表,该表具有在INSTEAD OF触发器中生成的主键。这可能是实现主键的最坏方法,但是它们基本上会获取最大值,将其递增1,然后使用此值作为键。这发生在触发器中。
我有一个.Net应用程序来启动RepeatableRead事务,并将记录插入此表中。只要我不尝试同时执行多个插入操作,此方法就可以正常工作。如果这样做,我会收到PK违反错误。在我看来,插入操作均被触发,触发器为每个事务获取相同的最后一个数字,将其递增1,然后尝试使用相同的新“标识符”插入两个记录。
我已经与设置此触发器的DBA进行过交谈,他认为RepeatableRead应该阻止这种情况的发生,因为它显然锁定了表的读取操作,而其他事务将等待释放锁。因此,实质上,我的交易将以串行方式进行。
因此,问题是,如果RepeatableRead以DBA描述的方式工作,为什么会遭到PK违反?
最佳答案
RepeatableRead无法解决该问题,因为它允许幻像插入,而这正是您在此处所拥有的。第二个插入是错误的,因为它没有“看到”先前的插入,并且您具有所描述的行为。
您可以通过可序列化的隔离或通过执行单独的事务来解决它(前者会增加争用,后者会减少争用,但是后者可能对您而言无效)。
确实,解决方法是用属性标识约束替换触发器,而不是使用触发器(可以在现有表上完成,尽管存在困难,尤其是如果正在使用复制),或者使用更好的算法来设置新价值。
关于c# - RepeatableRead似乎没有锁定读取,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5353431/