锁定对象的字段值

时间:2018-08-13 14:43:55

标签: java multithreading performance

我的微服务正在接收来自RabbitMQ的消息并将其存储在CouchDB中, 我正在创建多个使用者线程来处理它们,并且由于发生了竞争情况,所以我的代码引发ConflictUpdateException

  

线程X,Y同时读取同一对象的bed db值;线程X在线程Y之前更新Couch中的记录,但线程Y   基于X之前的哈希值(_rev)更新记录   修改的记录。

对象的唯一标识符是复合的:name + age + id,

  

如何仅对具有相同线程的线程执行关键部分   (name + age + id)吗?

我不想实现的可能方法:

  1. 锁定字符串值(名称+年龄+ id)。 [不是一个好习惯]

  2. String和CustomObjects的HashMap用于锁定。 [因为我对唯一对象的数量没有记忆]

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

我认为您应该跟踪_rev:

  • 获取文档,记下CouchDB发送的_rev属性
  • 编辑所需字段
  • 使用_rev属性将更新后的文档发送回去
  • 如果_rev与当前存储的号码匹配,请完成!
  • 如果存在冲突(当_rev不匹配时),请检索最新的文档版本,然后再次编辑需要编辑的内容。转到步骤3

答案 1 :(得分:0)

您将需要concurrentHashMap结构,并保持锁定的主键。 它们的表示取决于您,不鼓励使用的字符串将与实现 hashcode + equals 的某些特殊类的实例一样好。 您的使用者将通过调用原子 putIfAbsent()遍历试图锁定记录的输入队列。如果成功,它将执行其 storeToDatabase()调用,然后从该映射中进行 remove()条目。否则,移至队列中的下一个条目。

通过这种方式,在此锁定键映射中,您仅需要几个(消费者数量)条目, 没有大量的内存消耗,并且并行化级别会很高。不过,它不会保留收到的订单。