在《高性能 Java 持久性》一书的 6.3.3.3 部分中写道,在 MySQL 可重复读取隔离级别中可能会出现丢失更新现象。这是截图:
假设以下情况(隔离级别为 REPEATABLE READ):
tx1 | tx2
-----------------------------------------------------------------------------------
START TRANSACTION; |
SELECT * FROM test WHERE id = 1; |
( say, DB_TRX_ID = 7 at this moment) |
|
| START TRANSACTION;
| SELECT * FROM test WHERE id = 1;
| UPDATE test SET name="x" WHERE id = 1;
| COMMIT;(say, makes DB_TRX_ID = 10)
|
UPDATE test SET name="y" WHERE id = 1;|
COMMIT;
Run Code Online (Sandbox Code Playgroud)
问题:
tx1 提交后,MVCC 是否会检测到行版本(DB_TRX_ID)不再等于 7(而是 …
在提交当前事务之前,hibernate 检查该行的版本时,它应该发出一条 sqlselect语句来获取该行。
假设在发出该select语句后,hibernate 发现行版本没有改变,因此它应该继续提交事务。
我想知道 hibernate 如何确保在选择行和提交当前事务之间的时间段内没有任何其他事务会更新行更改其版本号?休眠可以做的唯一可能的事情似乎是使用悲观锁定的行版本选择Select ... For Update或具有这种隔离级别的事务,它将锁定正在读取的行。
如果我的想法是真的:
那么休眠乐观锁实际上确实对其操作使用了悲观锁,尽管悲观锁被持有的时间很短,因为事务将在此之后立即提交。
否则我们在行版本检查和提交之间有一个很短的时间段,可能会发生竞争条件。
请分享您的想法。
sql hibernate race-condition optimistic-locking pessimistic-locking
我想确保我的 Java 程序始终由显式指定的user.timezone属性运行。我-Duser.timezone=XXX作为命令行设置传递。
但是,当我完全省略该系统属性,然后在我的程序中检查 的值时System.getProperty("user.timezone"),它不是null,而是包含系统时区。因此,我无法终止我的程序,因为该属性的值永远不会为空。
我知道我可以使用自定义系统属性名称(比如tz)来接受时区 ID,然后TimeZone.setDefault(System.getProperty("tz"))在我的代码中执行,但我更喜欢使用系统属性user.timezone,它旨在用于这个原因。
有什么方法可以使用user.timezone系统属性来实现我所需要的吗?