繁体   English   中英

未提交的数据库事务和自动增量列

[英]Un-committed database transactions and auto-increment columns

我今天遇到了一些奇怪的行为,并想知道它是否是预期的或标准的。 我们正在使用Hibernate来对抗MySQL5。 在编码过程中我忘了关闭交易,我认为其他人可以联系。

当我最终关闭事务时,运行代码并检查表,我注意到以下内容。 我一直错误地运行我的代码而没有关闭事务,因此没有导致插入实际行,但是增加了自动增量代理主键值,因此我有一个间隙(即没有id字段值为751至762)。

这是预期的还是标准的行为? 它可能因数据库而异吗? 和/或Hibernate自己的事务抽象是否会对此产生一些可能的影响?

是的,这是预期的。

如果你考虑一下:数据库还能做什么? 如果您增加列,然后将其用作同一事务中其他插入的外键,并且当您正在执行其他人提交时,则他们无法使用您的值。 你会得到一个差距。

像Oracle这样的数据库中的序列工作方式大致相同。 一旦请求了特定值,它是否随后被提交无关紧要。 它永远不会被重用。 并且序列也不是绝对有序的。

这是非常期待的行为。 如果没有它,db必须等待已经插入记录的每个事务完成,然后再将新id分配给下一个插入。

是的,这是预期的行为。 该文档非常好地解释了它。

从5.1.22开始,实际上有三种不同的锁定模式可以控制并发事务如何获得自动增量值。 但是这三个都会导致回滚事务的间隙(回滚事务使用的自动增量值将被丢弃)。

数据库序列不保证id序列没有间隙。 它们被设计为与事务无关,只有这样才能是非阻塞的。

您不需要间隙,您必须编写自己的存储过程以在事务上增加列,但这样的代码将阻止其他事务,因此您必须是carrefull。

你从SEQUENCE_TABLE中选择CURRVAL WHERE TYPE =:YOUR_SEQ_NAME FOR UPDATE; UPDATE SEQUENCE_TABLE SET CURRVAL =:INCREMENTED_CURRVAL TYERE TYPE =:YOUR_SEQ。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM