我正在使用 JPA 2.0 的 Hibernate 实现在表行中创建一个计数器。我正在使用带有 InnoDB 引擎的 MySQL 5.5。我正在尝试锁定计数器行,以便 JVM 之外的任何进程都无法查看该计数器,直到我的代码将其递增。我的代码如下所示:
//inside a Transaction....
//key is an enum
final PropertyKey key = PropertyKey.DEPLOY_COUNTER;
final Query query =
entityManager.createQuery("FROM Property s where propertyKey = :key").setParameter("key", key);
query.setLockMode(LockModeType.PESSIMISTIC_WRITE);
LOG.debug("Blocking (maybe) while waiting to update deploy counter");
final Property counterAsProperty = (Property) query.getSingleResult();
try
{
Thread.sleep(15000);
//while sleeping I use MySQL cli to check value of property in database
}
catch (InterruptedException e)
{
e.printStackTrace();
}
//in java, increment counter by one and then save in db
//...
我使用 Thread.sleep() 在事务中间暂停代码。当线程处于休眠状态时,我使用 MySQL CLI 客户端登录到数据库并检查属性的值。该会话看起来像这样:
user@mypc [user]> begin work;
Query OK, 0 rows affected (0.00 sec)
user@mypc [user]> select * from property where property_key = 'DEPLOY_COUNTER';
+----+---------+-----------+--------------------+----------------+
| id | version | encrypted | property_key | property_value |
+----+---------+-----------+--------------------+----------------+
| 10 | 0 | 0 | DEPLOY_COUNTER | 66 |
+----+---------+-----------+--------------------+----------------+
请注意查询是如何立即返回的(0.00 秒),因为我预计它会阻塞,直到线程退出睡眠并且事务完成。我对 LockModeType.PESSIMISTIC_WRITE 的理解是它应该将检索到的行放在一个排他锁中,不能被另一个事务读取或写入。
注意:当线程处于休眠状态时,对这一行的更新会阻塞。
如果我设置了 PESSIMISTIC_WRITE 锁定模式,为什么另一个数据库连接可以在另一个事务正在运行时查看数据?