2

optimistic locking在 JPA 中研究过,@Version annotation在 DB 中添加了版本列以及它是如何由EntityManageretc管理的

文档说(用我自己的话)乐观锁在对象级别是有效的。我可以说确实如此,因为版本定义位于实体类中。

这表示:

  1. userA 选择 row_A (只是 db 表中的一行)

  2. 用户 B 选择 row_A

  3. userA 更新用户名列的 row_A (此处版本更改)

  4. userB 更新用户名列的 row_A(抛出 optimisticLockException)

到现在为止还挺好。

但是在第4步考虑,如果

userB update row_A of phoneNumber例如。

我知道仍然会抛出optimisticLockException,但是有没有办法按列级别而不是对象级别锁定?

对我来说,拥有列级锁会很好,但我也不确定这会带来什么缺点,即使它是可能的。

4

3 回答 3

2

不。请记住,JPA 所做的只是将对象映射到底层关系数据库。因此,表中的每条记录(行)最终都会成为对象的一个​​实例。

数据库通常锁定记录而不是列。锁定整列几乎就像在表上的排他锁。

于 2010-12-29T00:35:32.810 回答
2

公认的答案并不完全正确。在 vanilla JPA 级别确实如此,但是,您可以利用提供程序特定的功能来获取列级别锁。例如,Glassfish 3.0+ 中的默认提供程序 Eclipselink 支持 Optimistic 锁定扩展,在这方面提供了更大的灵活性。

请参阅Eclipselink JPA 扩展以获取乐观锁定

乐观版本锁定策略和级联

有关 Eclipselink 的 Optimistic 字段锁定策略的详细信息。

于 2011-08-22T17:11:32.610 回答
1

我可以看到这种锁定的使用,但它会违反数据库更新的原子性。想象一下,我正在编写一个银行应用程序,其中人们有余额和透支限制。说我开始:

Customer  | Balance | Overdraft Limit
Shirakawa |  -30000 |          -50000

然后白川先生出现了,通过不同的收银员同时进行了两笔交易;一个,他提取15000日元,另一个,他将透支限额降低到40000日元。这些事务中的每一个都可以单独使用,并且不会违反业务逻辑中的任何约束。但结果是:

Customer  | Balance | Overdraft Limit
Shirakawa |  -45000 |          -40000

哦哦。

我承认这是一个人为的例子。但这就是不支持列级并发更新的普遍原因。

但是,您可以做的是将记录的同时可更新部分分解为单独的实体,并分别更新它们。将其应用于上述示例,假设我们有一个如上所述的帐户表,还有一个透支协议表,具有一对一的关系。然后我们会有:

Customer  | Balance
Shirakawa |  -45000

Customer  | Overdraft Limit
Shirakawa |          -40000

我们可以并行更新它们。在这种情况下,这将是一个坏主意,但它可能对您有用。

于 2010-12-29T00:40:44.217 回答