我有一个包含名称和 name_count 的表。因此,当我插入一条新记录时,我首先检查该名称的最大 name_count 是多少。然后我插入最大值为 + 1 的记录。效果很好...除了 mysql 5.1 和 hibernate 3.5,默认情况下读取不考虑事务边界。同名的这些插入中的 2 个可能同时发生并以相同的 name_count 结束,这完全搞砸了我的应用程序!
不幸的是,在某些特定情况下,上述情况实际上相当普遍。那我该怎么办?我假设我可以做一个悲观锁,我读取的任何行都被锁定以供进一步读取,直到我提交或回滚我的事务。或者我可以使用自动不断尝试直到没有冲突的版本列进行乐观锁定?
什么是适合我的情况的最佳方法,我如何在 Hibernate 3.5 和 mysql 5.1 中指定它?上表内容庞大且访问频繁。
最佳答案
这就是为什么大多数人使用 SEQUENCE
来创建唯一数字的原因。也就是说,您必须做的是锁定整个表 (LOCK TABLES
)。问题:您必须锁定所有您需要的表(即任何 Hibernate 可能接触到的表),否则您将得到错误。接下来,您必须解锁表并与其余事务同步执行这两项操作。
我希望这能让您了解人们为什么使用序列:它们有一些小缺点,例如间隙,但其他一切都更糟糕。
[编辑] 您可以定义一个序列,然后使用 native SQL 查询来获取下一个值。您可以尝试定义一个序列生成器(请参阅 the docs ),但也许映射只允许在 Id 字段上使用。
关于“2亿个名字”:只要数据库能存储数字,你也可以在其上定义一个序列。
关于“基于行的锁定”:你打算锁定哪一行?有最大值的那个?我不确定 max()
运算符在锁定后是否会停止。你可以尝试的是 a trigger .由于触发器是原子的,因此没有人可以在它运行时插入一行。但是触发器有点难以维护。
关于mysql - 如何锁定事务以读取一行然后插入 Hibernate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2903059/