在基于微服务的系统中实现数据库一致性的最佳方式是什么?

GOTO in Berlin岁时,Martin Fowler谈到了微服务,他提到的一条"规则"是保留"每服务"数据库,这意味着服务不能直接连接到另一个服务"拥有"的数据库.

这是超级好和优雅,但在实践中,它变得有点棘手.假设您有几项服务:

  • 前台
  • 订单管理服务
  • 忠诚计划服务

现在,客户在您的前端进行购买,它将调用订单管理服务,该服务将保存数据库中的所有内容--没问题.此时,还将呼叫忠诚度计划服务,以便它从您的帐户贷记/借记积分.

现在,当所有内容都在同一个DB/DB服务器上时,一切都变得很容易,因为您可以在一个事务中运行所有内容:如果忠诚度计划服务无法写入数据库,我们可以回滚整个事务.

当我们在多个服务中执行DB操作时,这是不可能的,因为我们不依赖一个连接/不利用运行单个事务的优势.

我很想听听你的建议!..提前谢谢!

推荐答案

这是非常好和优雅,但在实践中它变得有点棘手

它的意思是"在实践中",您需要以这样的方式设计您的微服务,即在遵循规则的同时满足必要的业务一致性:

服务不能直接连接到另一个服务"拥有"的数据库.

换句话说,不要对他们的职责做出任何假设,并根据需要改变界限,直到你能找到一种方法来实现这一点.

现在,回答你的问题:

让事情保持一致并过上幸福生活的最佳模式是什么?

对于不需要立即一致性的事情,更新忠诚度积分似乎属于这一类,您可以使用可靠的发布/订阅模式将事件从一个微服务分派给其他微服务处理.可靠的一点是,您会希望事件处理内容具有良好的重试、回滚和幂等(或事务性).

如果你在 run .NET支持这种可靠性的基础设施的一些例子包括NServiceBusMassTransit.充分披露——我是NServiceBus的创始人.

Update:关于对忠诚度积分的担忧的 comments :"如果余额更新被延迟处理,客户实际上可能能够订购比他们的积分更多的商品".

许多人都在努力满足这些要求,以获得强大的一致性.问题是,这类场景通常可以通过引入额外的规则来处理,比如如果用户最终获得负忠诚度点,通知他们.如果T过go 了,而忠诚度点数没有被整理出来,通知用户,他们将根据某种转换率收取M.当客户使用积分购买物品时,该政策应该对他们可见.

Database相关问答推荐

TYPO3 OOPS,出现错误!编码:202402180809040864ba5c

Postgres和Oracle之间 Select 查询的结果差异

MongoDB根据嵌套文档中的值匹配数组

避免数据库联接的两个查询替换

哪个能够存储 1 亿条记录的嵌入式数据库具有高效的 C 或 C++ API

如何将 Grails 3.0 连接到我的本地 Mysql 数据库

如何将 MySQL 5.5.40 升级到 MySQL 5.7

授予对具有特定前缀的多个表的权限

每个请求可以多次查询 MongoDB 吗?

如何从 MySQL 行中修剪前导和尾随引号?

用于获取存储在单个表中的 n 级父子关系的 Postgresql 查询

如何处理 SQL Server 中列名中的空格?

为什么在连接表上有一个主键不好?

Android 上的测试数据库:ProviderTestCase2 还是 RenamingDelegatingContext?

在 SQLite 数据库中加入 3 个表

使用默认路径中的文件创建数据库

如何使用 Realm 进行排序?

MySQL中的eq_ref和ref类型是什么意思解释

与 IntelliJ IDEA 相比,DataGrip 附加值

python3k中的sqlite3中的cursor.rowcount总是-1