简体   繁体   English

如何在这种并发情况下确保数据一致性?

[英]How do I ensure data consistency in this concurrent situation?

The problem is this: 问题是这样的:

  • I have multiple competing threads (100+) that need to access one database table 我有多个需要访问一个数据库表的竞争线程(100+)
  • Each thread will pass a String name - where that name exists in the table, the database should return the id for the row, where the name doesn't already exist, the name should be inserted and the id returned. 每个线程都将传递一个String name - 该名称存在于表中,数据库应返回该行的id,该名称尚不存在,应插入名称并返回id。
  • There can only ever be one instance of name in the database - ie. 数据库中只能有一个name实例 - 即。 name must be unique 名称必须是唯一的

How do I ensure that thread one doesn't insert name1 at the same time as thread two also tries to insert name1 ? 如何确保线程1不会同时插入name1 ,因为线程2也尝试插入name1 In other words, how do I guarantee the uniqueness of name in a concurrent environment? 换句话说,如何保证并发环境中name的唯一性? This also needs to be as efficient as possible - this has the potential to be a serious bottleneck. 这也需要尽可能高效 - 这有可能成为一个严重的瓶颈。

I am using MySQL and Java. 我正在使用MySQL和Java。

Thanks 谢谢

Assuming there is a unique constraint on the name column, each insert will acquire a lock. 假设name列上有唯一约束,则每个insert都将获得一个锁。 Any thread that attempts to insert it a second time concurrently will wait until the 1st insert either succeeds or fails (tx commit or rolls back). 任何尝试同时插入第二次的线程将等到第一次insert成功或失败(tx提交或回滚)。

If the 1st transaction succeeds, 2nd transaction will fail with with a unique key violation. 如果第一个事务成功,则第二个事务将因唯一键冲突而失败。 Then you know it exists already. 然后你知道它已经存在了。

If there is one insert per transaction, it'ok. 如果每个事务有一个插入,那么它就是。 If there are more than 1 insert per transaction, you may deadlock. 如果每个事务有多个插入,则可能会死锁。

Each thread will pass a String name - where that name exists in the table, the database should return the id for the row, where the name doesn't already exist, the name should be inserted and the id returned. 每个线程都将传递一个String名称 - 该名称存在于表中,数据库应返回该行的id,该名称尚不存在,应插入名称并返回id。

So all in all, the algo is like this: 总而言之,算法是这样的:

1 read row with name
   2.1 if found, return row id
   2.2 if not found, attempt to insert
      2.2.1 if insert succeeds, return new row id
      2.2.2 if insert fails with unique constraint violation
          2.2.2.1 read row with name
          2.2.2.2 read should succeed this time, so return row id

Because there can be a high contention on the unique index, the insert may block for some time. 因为唯一索引可能存在高争用insert可能会阻塞一段时间。 In which case the transaction may time out . 在这种情况下,交易可能会超时 Make some stress test, and tune the configuration until it works correctly with your load. 进行一些压力测试,并调整配置,直到它与您的负载正常工作。

Also, you should check if you get a unique constraint violation exception or some other exception. 此外,您应该检查是否获得了唯一约束违例异常或其他一些异常。

And again, this works only if there is one insert per transaction, otherwise it may deadlock . 而且,这仅在每个事务有一个插入时才有效,否则可能会死锁


Also, you can try to read the row at step 1 with " select * for update ". 此外,您可以尝试使用“ select * for update ”读取步骤1中的行。 In this case, it waits until a concurrent insert either commits or succeeds. 在这种情况下,它会等待并发插入提交或成功。 This can slightly reduce the amount of error at step 2.2.2 due to the contention on the index. 由于索引上的争用,这可以略微减少步骤2.2.2中的错误量。

在数据库中的名称列上创建唯一约束。

为name列添加唯一约束。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何通过objectify确保与Appengine实体上的并发请求的一致性? - How to ensure consistency with concurrent requests on Appengine entities with objectify? 如果必须将 setter 值写入文件,如何确保数据一致性? - How can I ensure data consistency if a setter value must be written into a file? 如何确保多个模型对象实例之间的一致性 - How can I ensure consistency between multiple model object instances 在休眠状态下更新多个表并确保数据一致性 - Updates multiple tables in hibernate and ensure data consistency 如何解决此内存一致性错误? - How do I solve this memory consistency error? 如何确保Java序列化中枚举的一致性? - How to ensure consistency of enums in Java serialization? 如何针对这种情况创建休眠映射? - How do i create hibernate mappings for this situation? 在这种情况下,如何实现OnCompletionListener? - How do I implement an OnCompletionListener for this situation? 如何确保数据库一致性-群集应用程序共享公共数据库 - How to ensure db consistency - clustered application sharing common db Java NIO:从Channel读取不包含任何数据的数据。 如何处理这种情况? - Java NIO: Read data from Channel which does not contain any data. How do I handle this situation?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM