Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java (ObjectOptimisticLockingFailureException)单个事务中的StaleStateException_Java_Mysql_Hibernate_Spring Transactions_Optimistic Locking - Fatal编程技术网

Java (ObjectOptimisticLockingFailureException)单个事务中的StaleStateException

Java (ObjectOptimisticLockingFailureException)单个事务中的StaleStateException,java,mysql,hibernate,spring-transactions,optimistic-locking,Java,Mysql,Hibernate,Spring Transactions,Optimistic Locking,为了避免不必要的干扰,下面的代码被刻意简化和删节 我已使用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_U

为了避免不必要的干扰,下面的代码被刻意简化和删节

我已使用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事务方法

@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);

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

如果我们省略了第二个查询(该查询返回null!),那么该方法将正常工作

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

没有不同的线程或HTTP调用使用同一个DB行(根据我在本地机器上复制的情况)。唯一的区别是,在第一种情况下(错误),我们在数据库中进行第二次搜索并出现错误(即使第二次搜索没有返回任何结果),而在第二种情况下(成功),我们没有这样做

我知道(在错误情况下)Hibernate会在执行对DB的第二次调用之前刷新更改,以支持一致性。但是为什么我们会有StaleStateException,因为我们处理它的每件事一个事务,并且在其中所做的每一个更改都应该是自己可见的


有人能帮我解决这种奇怪的休眠行为,并解释为什么会发生这种情况。

我已经准备了一个可复制的最小应用程序,并将其放在bitbucket上:

我还在Hibernate项目的Jira中提出了一个问题:

Hibernate团队帮了我。事实证明,这个问题是由Hibernate和MySql错误造成的,这两个错误都与刷新过程中的精度损失有关

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

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