微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring Data JPA + Hibernate:开放式锁定无法按预期进行

如何解决Spring Data JPA + Hibernate:开放式锁定无法按预期进行

我有一个关于使用弹簧数据jpa和休眠状态进行乐观锁定的问题。我知道不同锁定类型的理论背景,以及乐观锁定应如何工作,但即使是简单的测试也不会引发任何锁定异常。

我有一个带有version属性的简单实体:

@Entity
@Table( name = "DOK_AUDIT",schema = "ORACLE" )
@SuppressWarnings( "unused" )
public class DocAudit {

    @Id
    @GeneratedValue( strategy = GenerationType.IDENTITY )
    @Column( name = "AUDIT_ID" )
    private Long id;

    ...
    @Version
    @Column( name = "VERSION" )
    private Long version;

    @Column( name = "CHANGE_USER" )
    private String changeUser;
}

我创建了一种简单的事务服务方法,其中应更新一行

@Transactional
public void changeWithId(final Long auditId) {
    Preconditions.checkArgument(auditId != null,"auditId can't be null");

    final DocAudit auditById = auditRepository.getAuditById(auditId);
    auditById.setName("xxx");
}

现在,在事务提交之前,我在函数的最后一行添加一个调试器断点,并且将执行更新语句。

当调试器到达这一点时,我更改了数据库中的行并增加了版本。 现在,当恢复应用程序时,我可以看到将执行update语句,并使用where子句中的更正的版本列

update oracle.dok_audit set version=?,change_user=?,audit_name=?,audit_start_date=? where audit_id=? and version=?

由于where子句与数据库中的任何行都不匹配,因此update语句返回0(未更改任何行),但不会引发ObjectOptimisitcLockingException。

据我所知,hibernate / spring数据存储库现在应该抛出此异常,因为版本不匹配和更新不会影响任何行。

我想念什么?

当我对不同的事务执行读取和更新时,将发生乐观的锁定执行。在下面的示例中,我在保存功能之前添加一个断点,然后再次更改了数据库中的版本

// getAuditById is transactional
final DocAudit audit = auditService.getAuditById(2L);
audit.setName("changed");
// save audit is another transaction
auditService.saveAudit(audit);

当我现在使用此分离的实体调用saveAudit(调用存储库的保存功能)时,实体管理器必须合并分离的实体。当从数据库中选择实体以将其重新附加到上下文时,由于版本不匹配,将引发光学标记锁定异常。

可以,但是为什么在一个事务中更改实体时,第一个示例中的光学标记锁定不起作用?

谢谢 塞巴斯蒂安

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。