消息排队消息之间的依赖性

Nor*_*ard 5 multithreading message-queue rabbitmq

这是我的情况:

  • 我有两个服务器,每个服务器上都有一个多线程消息队列使用者(总共两个使用者)。
  • 我有很多消息类型(CreateParent,CreateChild等)
  • 我受制于糟糕的旧版代码(创建一个孩子会部分创建一个父母。我知道这很糟糕……但我无法改变。)
  • 不能假定消息排序(消息排队原则!)
  • RabbitMQ是我的消息队列代理。

我的问题:

  • 当两个线程同时运行(一个线程执行CreateParent,另一个线程执行CreateChild)时,它们会产生冲突,因为两个线程试图在数据库中创建Parent(记住旧代码!)。

我最初的解决方案:

  • 在消费者内部,我创建了“实体锁定”概念。因此,例如,当线程处理CreateChild消息时,该线程将锁定Child和Parent(旧代码!),以便CreateParent消息处理可以等待。我使用基本的.net Monitor和ID列表来实现此概念。它运作良好。

我最初的解决方案限制:

  • 我的“实体锁定”概念适用于单个服务器上单个进程中的单个使用者。但是它不能在运行多个使用者的多台服务器上工作。
  • 我正在考虑使用共享数据库“存储”我的实体锁定概念,以便每个进程(和线程)都可以访问数据库以验证哪些实体被锁定。

我的问题(最终!):

所有这些都变得非常复杂,并且增加了错误风险和代码维护问题。我真的不喜欢它!有没有人已经遇到过这种问题?他们可以接受的解决方法吗?有人对我的方案有一个干净的解决方案的想法吗?

谢谢!

Nor*_*ard 1

最后,简单的解决方案总是更好的!

我最终拒绝在执行请求之前预先验证所有必需的数据和实体状态,而不是使用“实体锁定”概念的所有复杂性。

更准确地说,当 CreateChild 进程遇到由 CreateParent 创建的现有数据时,我不会让 CreateChild 进程自行崩溃,而是在执行 CreateChild 消息之前完全验证数据库中的一切正常。

此解决方案的缺点是 CreateChild 的实现必须知道 CreateParent 将生成哪些特定数据,并在开始执行之前验证它的存在。但说真的,这比跨系统锁定所有内容要好得多!