乐观锁定的 JPA 版本字段的最佳类型

Posted

技术标签:

【中文标题】乐观锁定的 JPA 版本字段的最佳类型【英文标题】:Best type for JPA version field for Optimistic locking 【发布时间】:2014-07-06 12:47:46 【问题描述】:

对于使用 @Version 注释的字段在 JPA 中进行乐观锁定,哪种类型是最佳类型存在疑问。

API javadoc (http://docs.oracle.com/javaee/7/api/javax/persistence/Version.html) 说:

“版本属性支持以下类型:int、Integer、short、Short、long、Long、java.sql.Timestamp。”

在其他页面 (http://en.wikibooks.org/wiki/Java_Persistence/Locking#Optimistic_Locking) 说:

"JPA 支持使用乐观锁定版本字段,该字段在每次更新时都会更新。该字段可以是数字或时间戳值。建议使用数字值,因为数字值更精确、可移植、高性能且更易于处理比时间戳。”

“如果表已经有最后更新的时间戳列,则经常使用时间戳锁定,这也是自动更新最后更新的列的便捷方式。时间戳版本值可能比数字版本更有用,因为它包括对象上次更新时间的相关信息。”

我的问题是:

如果您要拥有一个 lastUpdated 字段,最好使用 Timestamp 类型,还是最好使用数字版本字段和其他字段中的时间戳?

在数值类型(int、Integer、short、Short、long、Long)之间最好选择哪个(考虑每种类型的长度)?我的意思是,我认为最好的是 Long,但每行需要很大的空间。

当版本字段到达数字类型的最后一个数字(例如,短字段中的 32,767)时会发生什么?在下一个增量中会再次从 1 开始吗?

【问题讨论】:

【参考方案1】:

首先,要知道锁定是用来管理并发事务的。

1.分离您的担忧。如果 lastupdated 字段是特定于业务模型的,它应该与您的版本控制字段(用于版本控制)分开。

2.Primitives 和 objects 通常映射到您的数据库作为相同的类型。除了默认情况下布尔值可以为空并且布尔值“不可为空”这一事实。但是,明确强制为空性。在这种情况下,您想使用原语,因为版本字段不能为空。

整数或长整数比时间戳好。 Hibernate recommends numeric versionig 他们不会占用太多空间。

    如果你用了很长时间,你可能活不下去了。

使用这个,你应该没问题。

private long version;

@Version
public long getVersion() 
    return version;


public void setVersion(long version) 
    this.version = version;

【讨论】:

【参考方案2】:

只需使用 Long 或 Integer。 但不要使用 int 或 long。 与此处的其他评论相反,当实体从未被持久化时,预期为空值。 拥有 int 或 long 可能会使 Hibernate 认为实体已经被持久化并且处于分离状态,因为版本值在未设置时将为 0。 刚刚调试完 FK 违规,其中“int”是原因,所以节省您的时间,只需使用 Long 或 Integer。

【讨论】:

正如 Piotr 所说:“......当实体从未被持久化时,预期为空值......”

以上是关于乐观锁定的 JPA 版本字段的最佳类型的主要内容,如果未能解决你的问题,请参考以下文章

JPA 和乐观锁定模式

使用 JPA / Hibernate 在无状态应用程序中进行乐观锁定

乐观锁定的重试机制(spring data + JPA)

mybatis 乐观锁和逻辑删除

mybatis 乐观锁和逻辑删除

mybatis 乐观锁和逻辑删除