具有作业的共享数据库

时间:2019-02-20 16:44:37

标签: database concurrency locking multiple-instances

问题源自与同事的讨论。

TLDR :对我来说,我们可能不是第一个拥有多个服务器从数据库读取作业的公司/团队,我想知道“合适的”架构是什么?提出的解决方案(每个服务器将其ID写入数据库中的请求,然后仅处理其自身的请求)是正确的解决方法,或者针对此问题是否有更好的体系结构?我建议所有服务器都应处理所有作业,并将记录标记为“进行中”或将其锁定或类似的东西)?难道真的,数据库仅返回非锁定记录是一种新奇的功能吗?在此功能存在之前是如何完成的?


要解决的任务

    服务接收请求:请求基本上说“请在交易X完成时通知我”。交易由调用服务的人无法访问的第三方完成。
  • 交易X完成后,必须调用服务的调用方。

这些是客户要求的固定部件。

在讨论期间,我正在挑战解决方案的体系结构,但由于我不够专业,因此我可能正在监督问题。

正在实施的解决方案

  • 该服务将每个请求写入数据库
  • 定时bean应该定期检查数据库中是否有待处理的请求。对于每个未决请求,请向第三方查询有关交易的信息:如果交易完成,请通过回调通知原始调用者,并将请求标记为已在数据库中处理。

到目前为止还不错:现在的问题是,我们处于一个分布式环境中,其中有多个服务器正在向数据库写入数据,每个服务器都运行一个定时bean。

我对此持怀疑态度: 为了避免并发问题并多次调用回调,其思想是每个服务器将其ID写入它写入数据库的请求中,并且只有定时Bean才分别检查相应的记录。因此,服务器ABC上的定时bean将仅处理服务器ABC上运行的服务的请求。

对我来说,这感觉不对-恕我直言: 哪个服务向数据库写入请求都没有关系。我认为每个定时bean都应该能够处理任何待处理的请求。但是一位同事说这是不可能的,因为服务器将如何知道是否正在处理记录?我认为如果服务器正在处理记录,则应该将其锁定或标记为“进行中”。但是有人争辩说,然后另一台服务器将被阻塞,以等待该挂起的请求-讨论来回进行,我发现一个服务器实际上只能查询未锁定的记录(例如:Select only unlocked rows mysql)。然后有人争辩说,这可能是一个非常新奇的功能,与“每个服务器仅处理自身写入数据库的请求”方法相比,它可能更安全,更简单,更好。讨论的另一点是服务器是应获取所有待处理的请求还是仅获取单个请求-在该选项中,每个服务器仅获取其自己的请求,显然所有这些请求都应被提取。我们可以假设这样做会负担很重(每秒可能将数百或数千个请求写入数据库的顺序)-因此性能是一个问题。

顺便说一句。想法是,如果服务器制动,则该请求迟早会超时,并且将执行一个新请求(然后,负载均衡器会将其路由到正常工作的服务器)。正如您可能已经猜到的那样,我们处于Java企业环境中,但实际上我对此并不在意。

0 个答案:

没有答案