Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.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
Hibernate 在高负载期间在mysql中创建多个记录_Hibernate_Concurrency_Spring Data_Spring Data Jpa_Spring Transactions - Fatal编程技术网

Hibernate 在高负载期间在mysql中创建多个记录

Hibernate 在高负载期间在mysql中创建多个记录,hibernate,concurrency,spring-data,spring-data-jpa,spring-transactions,Hibernate,Concurrency,Spring Data,Spring Data Jpa,Spring Transactions,我在一个SpringDataJPA应用程序中工作。正如我们所知,通过应用spring@Transactional注释,它遵循ACID属性。然而,我有一个问题。以下是我的解释 在我当前的应用程序中,给定帖子的业务规则允许用户只回答一个答案,如果他想修改他的答案,他可以编辑一个答案,但不能为同一帖子创建另一个答案。因此,对于创建和修改答案,我有两种方法。1.保存方法2。编辑方法 我的问题是,w.r.t保存的答案有时在生产中不符合预期,即它不符合业务规则,并且为同一帖子的同一用户创建了两个答案。但在当

我在一个SpringDataJPA应用程序中工作。正如我们所知,通过应用spring@Transactional注释,它遵循ACID属性。然而,我有一个问题。以下是我的解释

在我当前的应用程序中,给定帖子的业务规则允许用户只回答一个答案,如果他想修改他的答案,他可以编辑一个答案,但不能为同一帖子创建另一个答案。因此,对于创建和修改答案,我有两种方法。1.保存方法2。编辑方法

我的问题是,w.r.t保存的答案有时在生产中不符合预期,即它不符合业务规则,并且为同一帖子的同一用户创建了两个答案。但在当地环境中,这个问题从未发生过。编辑方法对本地环境和生产环境都适用

下面是我的业务逻辑中save方法的示例代码段

@Transactional
public void save(Answer answer) {
    Integer postId = answer.getQuestionId();
    Answer answerFromDb = answerRepository.findByPostIdAndCreatedByIdAndIsDeleted(postId, answer.getCreatedById(), false);
    if(null != answerFromDb) {
        throw new InvalidException("You have already answer for the current post");
    }
    answerRepository.save(answer);
}
我们使用的是mysql 5.6,在本地和生产环境中,默认隔离级别都是可重复读取的。i、 e

mysql> SHOW VARIABLES LIKE 'tx_isolation';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tx_isolation  | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)
注意:所有主键都是自动递增的,并且在生产环境中有一个mysql服务器实例,目前它还不是集群

如能对上述问题有所了解,我们将不胜感激。

可重复阅读:

T1事务从表应答中读取数据并返回一定数量的行。T1中的每个后续读取都将具有相同的行。如果另一个并发事务(T2)在T1启动后在表Answers上插入一行,它(T1)将不知道有一个新行

因此,一种可能的解决方案是在Answers表上添加一个唯一的键,以便它匹配
findByPostIdAndCreatedByIdAndIsDeleted
where条件

ALTER TABLE `Answers` ADD UNIQUE `unique_index`(`post_id`, `createdBy_id`, `deleted`);
并使用try包装保存:

try {
    answerRepository.save(answer);
} catch (DataIntegrityViolationException e) {
    // ignore (there is already an answer)
}
可重复读取:

T1事务从表应答中读取数据并返回一定数量的行。T1中的每个后续读取都将具有相同的行。如果另一个并发事务(T2)在T1启动后在表Answers上插入一行,它(T1)将不知道有一个新行

因此,一种可能的解决方案是在Answers表上添加一个唯一的键,以便它匹配
findByPostIdAndCreatedByIdAndIsDeleted
where条件

ALTER TABLE `Answers` ADD UNIQUE `unique_index`(`post_id`, `createdBy_id`, `deleted`);
并使用try包装保存:

try {
    answerRepository.save(answer);
} catch (DataIntegrityViolationException e) {
    // ignore (there is already an answer)
}

Hey@NikolaB曾想过在“postId”、“createdById”和“isDeleted”上添加唯一约束,这将阻止创建更多记录。但他很想知道为什么创建这两个记录时使用的隔离级别repetable read比read_COMMITED更严格。我对你解释的方式有些模糊的想法。感谢它证实了我的理解。Hey@NikolaB曾想过在“postId”、“createdById”和“isDeleted”上添加唯一的约束,这将阻止创建更多的记录。但他很想知道为什么创建这两个记录时会使用比read_committed更严格的隔离级别repetable read。我对你解释的方式有些模糊的想法。谢谢,这证实了我的理解。