使用乐观锁定在JPA 2中检查提交时读取集的版本

时间:2022-01-30 00:54:40

I'm using optimistic locking in a JPA2 (using EclipseLink v2.4) application (no container, just JavaSE). I'm trying to implement strong consistency, so I want the versions of all objects read during a transaction to be checked at commit.

我在JPA2(使用EclipseLink v2.4)应用程序(没有容器,只是JavaSE)中使用乐观锁定。我正在尝试实现强一致性,所以我希望在提交时检查事务期间读取的所有对象的版本。

When I use MySQL as the target DB, things happen as I expect: when I have a client performing read-only transactions concurrent with a client performing writes, some of the read-only transactions abort (and are retried).

当我使用MySQL作为目标数据库时,事情就像我期望的那样发生:当我的客户端执行与客户端执行写入并发的只读事务时,一些只读事务会中止(并重试)。

However, when I use HSQLDB (v2.2.9), the read-only transactions never abort. In fact, tcpdump shows nothing going across the wire at all!

但是,当我使用HSQLDB(v2.2.9)时,只读事务永远不会中止。事实上,tcpdump根本没有显示任何内容!

What's going on here? I've tried playing around with the isolation level to no avail. I don't see why that would matter anyway -- it seems like EclipseLink should be generating the roughly same SQL regardless of isolation. Maybe some weird optimization is going on?

这里发生了什么?我试过玩隔离级别无济于事。我不明白为什么这才重要 - 似乎EclipseLink应该生成大致相同的SQL而不管隔离。也许一些奇怪的优化正在进行?

Reading the JPA spec is confusing. Am I even guaranteed that my read set versions will be checked, or only the versions of objects that are modified or deleted?

阅读JPA规范令人困惑。我甚至保证会检查我的读取集版本,还是只保证修改或删除的对象版本?

2 个解决方案

#1


1  

Isolation level could explain why some things work in MySql (e.g if set to Serializable), but as you said, optimistic locking does not need that (but as said, may be it is not the optimistic locking that works in MySql).

隔离级别可以解释为什么有些东西在MySql中工作(例如,如果设置为Serializable),但正如你所说,乐观锁定不需要(但正如所说,可能不是在MySql中工作的乐观锁定)。

I would try to upgrade/downgrade the HSQLDB version for a quick check that it is not a BUG there.

我会尝试升级/降级HSQLDB版本,以便快速检查它是不是那里的BUG。

Also I suppose that you checked that you entities have fields annotated with @Version and that you lock EXPLICITLY the entities (by passing a LockModeType when you call EntityManager.find(), refresh() or lock()), as it is not clear if/which is the default LockModeType (check this discussion).

另外我想你检查过你的实体是否有用@Version注释的字段,并且你实际上锁定了实体(通过在调用EntityManager.find(),refresh()或lock()时传递一个LockModeType),因为它不清楚if / which是默认的LockModeType(查看本讨论)。

Also, if you want to debug a bit more, you could look what queries are sent to HSQL (take a look here and here too see how to log the queries). Specifically I would check how the @Version-annotated fields are updated/checked. Of course with the debugger attached.

此外,如果您想再调试一下,您可以查看将哪些查询发送到HSQL(请在此处查看,此处也可以查看如何记录查询)。具体来说,我会检查@ Version-annotated字段是如何更新/检查的。当然附带调试器。

Of course, without the code it is not so easy to say what could be the problems, but I suppose it is a problem in code.

当然,没有代码就不容易说出可能出现的问题,但我认为这是代码中的一个问题。

#2


0  

HSQL is an in-memory database, that probably has something to do with it. Are both your client in different JVMs? Probably not the best database for your needs.

HSQL是一个内存数据库,可能与它有关。您的客户端是否位于不同的JVM中?可能不是满足您需求的最佳数据库。

#1


1  

Isolation level could explain why some things work in MySql (e.g if set to Serializable), but as you said, optimistic locking does not need that (but as said, may be it is not the optimistic locking that works in MySql).

隔离级别可以解释为什么有些东西在MySql中工作(例如,如果设置为Serializable),但正如你所说,乐观锁定不需要(但正如所说,可能不是在MySql中工作的乐观锁定)。

I would try to upgrade/downgrade the HSQLDB version for a quick check that it is not a BUG there.

我会尝试升级/降级HSQLDB版本,以便快速检查它是不是那里的BUG。

Also I suppose that you checked that you entities have fields annotated with @Version and that you lock EXPLICITLY the entities (by passing a LockModeType when you call EntityManager.find(), refresh() or lock()), as it is not clear if/which is the default LockModeType (check this discussion).

另外我想你检查过你的实体是否有用@Version注释的字段,并且你实际上锁定了实体(通过在调用EntityManager.find(),refresh()或lock()时传递一个LockModeType),因为它不清楚if / which是默认的LockModeType(查看本讨论)。

Also, if you want to debug a bit more, you could look what queries are sent to HSQL (take a look here and here too see how to log the queries). Specifically I would check how the @Version-annotated fields are updated/checked. Of course with the debugger attached.

此外,如果您想再调试一下,您可以查看将哪些查询发送到HSQL(请在此处查看,此处也可以查看如何记录查询)。具体来说,我会检查@ Version-annotated字段是如何更新/检查的。当然附带调试器。

Of course, without the code it is not so easy to say what could be the problems, but I suppose it is a problem in code.

当然,没有代码就不容易说出可能出现的问题,但我认为这是代码中的一个问题。

#2


0  

HSQL is an in-memory database, that probably has something to do with it. Are both your client in different JVMs? Probably not the best database for your needs.

HSQL是一个内存数据库,可能与它有关。您的客户端是否位于不同的JVM中?可能不是满足您需求的最佳数据库。