Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.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 如何使用spring确保数据库更新语句中没有竞争条件_Java_Database_Spring_Spring Boot_Concurrency - Fatal编程技术网

Java 如何使用spring确保数据库更新语句中没有竞争条件

Java 如何使用spring确保数据库更新语句中没有竞争条件,java,database,spring,spring-boot,concurrency,Java,Database,Spring,Spring Boot,Concurrency,假设有两个实体儿童和礼物。假设有1000个孩子和10件礼物。孩子们总是试图抓住可用的礼物,礼物将被贴上“先到先得”的标签 表结构 子项表 +----+------+ | id | name | +----+------+ | 1 | Sam | | 2 | John | | 3 | Sara | +----+------+ +----+---------+-------------+ | id | gift | children_id | +----+---------+----

假设有两个实体
儿童
礼物
。假设有1000个孩子和10件礼物。孩子们总是试图抓住可用的礼物,礼物将被贴上“先到先得”的标签

表结构

子项

+----+------+
| id | name |
+----+------+
|  1 | Sam  |
|  2 | John |
|  3 | Sara |
+----+------+
+----+---------+-------------+
| id |  gift   | children_id |
+----+---------+-------------+
|  1 | Toy Car |           2 |
|  2 | Doll    |           3 |
+----+---------+-------------+
礼品
表格

+----+------+
| id | name |
+----+------+
|  1 | Sam  |
|  2 | John |
|  3 | Sara |
+----+------+
+----+---------+-------------+
| id |  gift   | children_id |
+----+---------+-------------+
|  1 | Toy Car |           2 |
|  2 | Doll    |           3 |
+----+---------+-------------+
这里的
children\u id
是最先抢走礼物的孩子

在我的应用程序中,我希望以这样的方式更新
children\u id
,即只有发起请求的第一个孩子才能获得请求,其余孩子将获得
GiftUnavailableException

我如何确保,即使一次有1000个请求来获取特定的礼物,也只有第一个会得到。或者我将如何确保此更新没有竞争条件

是否有任何特定于spring的特性可供我使用,或者是否有其他方法


我正在使用spring boot作为我的后端。

我无法发表评论,所以我来了

我假设您使用的是Spring数据JPA

然后您应该使用
@Transactional
注释:这意味着每次请求数据库时,您都要执行一个事务:

  • 开始交易
  • 执行事务
  • 提交事务
  • 这方面有很多有用的信息(请阅读!!):

    您需要将事务隔离种子设定为可序列化,并可能更改传播方法


    如果您没有使用Spring数据JPA。。这里有一个同步关键字,但我认为在这里使用它有点糟糕。

    如果一台机器上有多个线程,请使用
    同步。确保在事务中执行。2.首先对一份
    礼物进行独占锁定
    ——比如说,
    @lock(LockModeType.悲观)礼物findOne(Long id)
    。3.一旦检索到
    礼物
    ,立即检查该礼物是否未被认领。如果是,则退出(抛出异常、返回错误等)。4.如果该礼物尚未被认领,请将认领人分配给该礼物,然后保存。通过这种方式,许多索赔可以并行处理,只要它们是针对不同礼物的,同时,针对相同礼物的并发索赔将被拒绝,即使它们在不同的机器上运行。