((ObjectOptimisticLockingFailureException)单个事务中的StaleStateException

问题描述 投票:0回答:1

下面的代码被有意简化和删节,以避免不必要的干扰。

我有带有表的mysql数据库:

CREATE TABLE `payment` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `status` varchar(45) DEFAULT NULL,
  `last_update_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1

我有从控制器调用的Spring Transactional方法。

@GetMapping("/reproduce_error")
    @Transactional
    public ResponseEntity reproduceErrorOnUpdate(Long id) {
        try {
            Payment payment = paymentDao.getPayment(id); //1st query
            payment.setStatus(payment.getStatus().equals("A") ? "B" : "A");
            paymentDao.findAllByStatus("NOT EXISTING STATUS"); // 2nd query
            payment.setStatus("C");
        } catch (Exception e) {
            return new ResponseEntity<>(e, HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity(HttpStatus.OK);

    }

当我调用此方法时,我总是有一个例外:

org.springframework.orm.ObjectOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

但同时(这是最奇怪的事情):

如果省略第二个查询(无论如何返回null!),则该方法正确运行!

两个方法都在SINGLE事务中执行!(这就是我对它们的称呼,因此您可以看到某处没有其他交易

没有相同的数据库行使用不同的线程或HTTP调用(根据我在本地计算机上重现的内容)。唯一的区别是,在第一种情况(错误)中,我们在数据库中进行了第二次搜索,但有一个错误(即使第二次搜索未返回任何内容),在第二种情况(成功)中,我们没有这样做。

我知道(在错误情况下)Hibernate在执行第二次对DB的调用之​​前刷新更改以支持一致性。但是为什么在我们DO处理它的所有<< [ONE事务以及其中所做的所有更改都对自己可见的情况下又出现StaleStateException。

有人可以帮助我解决这种奇怪的休眠行为,并解释为什么会发生这种情况。
java mysql hibernate spring-transactions optimistic-locking
1个回答
0
投票
我已经准备了最小的可复制应用程序,并将其放置在bitbucket上:https://bitbucket.org/gegunov/hibernate_issue

我还在Hibernate项目的吉拉(Jira:https://hibernate.atlassian.net/browse/HHH-13867]出票了>

Hibernate团队为我提供了帮助。事实证明,此问题是由于刷新期间Hibernate和MySql错误与精度损失相关的结果。

解决方法之一是将数据库列格式从TIMESTAMP更改为(例如TIMESTAMP(6)或DATETIME(6)。

© www.soinside.com 2019 - 2024. All rights reserved.