mysql - 如何锁定事务以读取一行然后插入 Hibernate?

标签 mysql hibernate transactions insert locking

我有一个包含名称和 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/

相关文章:

php - Yii2:选择距离并映射到模型

php - 为 codeIgniter ErrorException [8192] : mysql_real_escape_string() 设置数据库

java - 无法创建 sessionFactory 对象.java.lang.NullPointerException

java - hibernate 中具有自定义实体的多对多 - 级联无法正常工作

mysql - 即使其中一项操作失败,事务也不会失败

mysql - 目录 : how do I test my app against multiple databases?

php - 如何在 PHP 中使用 OR 运算符?

java - Hibernate 无法解析嵌入类的属性

android - 动画 fragment 和返回堆栈

c# - 如何处理 TransactionInDoubtException