是否可以在JPA toplink中进行列级乐观锁定?

时间:2010-12-29 00:15:49

标签: java jpa toplink optimistic-locking

我在JPA中研究了optimistic locking,在数据库中添加了@Version annotation版本列,以及EntityManager等如何管理

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

这意味着:

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

  2. userB select row_A

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

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

  5. 到目前为止一切顺利。

    但是在第4步考虑,如果

    例如

    userB update row_A of phoneNumber

    我知道仍然会抛出optimisticLockException,但是否有任何方法可以按列级而不是对象级锁定?

    对我来说,拥有列级锁定会很好,但我也不确定即使有可能会带来什么样的劣势。

3 个答案:

答案 0 :(得分:2)

没有。请记住,JPA正在做的只是将对象映射到底层的Relational数据库。因此,表中的每个记录(行)最终都是对象的实例。

数据库通常锁定记录而不是列。锁定整列几乎就像桌子上的独占锁。

答案 1 :(得分:2)

接受的答案并非完全正确。但是,在vanilla JPA级别上,您可以利用提供程序特定的功能来获取列级锁定。例如,Glasscl 3.0+中的默认提供程序Ec​​lipselink支持乐观锁定扩展,可在此区域提供更大的灵活性。

请参阅Eclipselink JPA Extensions for Optimistic locking

Optimistic Version Locking Policies and Cascading

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

答案 2 :(得分: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

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