微服务通过另一个微服务访问DB,同时保持ACID保证



请帮助我理解这个与微服务相关的数据共享概念,我正在努力学习最佳实践。

假设我有一个Lambda函数(微服务)A,专门设计用于在DynamoDB表(NoSQL)上执行CRUD操作。我有一些用例触发这个函数来更新表中的特定项。

我有另一个微服务B,它需要读取和写入相同的数据库表。如果我要让这个微服务B直接在DynamoDB表上执行CRUD,这将是一个坏主意,因为现在AB都被配置为在表上单独操作,因此ACID保证丢失。(对吗?)

为了防止这种情况,这是最好的解决方案吗?:

  • 取消微服务B
  • 无论触发B的事件是什么,让它触发A来执行相应的数据库CRUD操作。

这会维持ACID保证吗?

我不确定2微服务是如何违反ACID属性的。下面是这些属性,并描述了多个生产者是如何影响它的。

原子性

事务通常由多条语句组成。原子性保证每个事务被视为单个"单元",要么完全成功,要么完全失败:如果构成事务的任何语句未能完成,则整个事务失败,数据库保持不变。

  • 有两个生产者不会破坏原子性

一致性一致性确保事务只能将数据库从一种一致状态带到另一种状态,保持数据库的不变性:根据所有定义的规则,写入数据库的任何数据必须有效,包括约束、级联、触发器和它们的任何组合。

  • 有两个生产者不会破坏一致性

隔离事务通常并发执行(例如,多个事务同时读写一个表)。隔离确保事务的并发执行使数据库处于与顺序执行事务时所获得的状态相同的状态。

  • 我认为你认为隔离是你的问题所在,但是所有对DynamoDB的写入都是强序列化的,因此是隔离的

耐久性

持久性保证事务一旦提交,即使在系统故障(例如,停电或崩溃)的情况下,它也将保持提交。

  • 拥有两个生产者并不会破坏耐久性

Wiki

如果我正确理解你的问题,它不是关于微服务或ACID,而是更多关于数据一致性。再一次,如果我的假设正确,你的问题应该是"我怎么能确保数据是一致的,当几个客户端-无论他们是在相同的过程或不同-试图读取和更新相同的数据(文档,行)?">

根据需求,有几种策略可以处理此问题。

  • 如果您使用的持久性技术支持,您可能会使用一些具有严重副作用的数据锁定机制或

  • 你可以尝试使用乐观锁实现,这可能需要在你的用例中进行一些更改。

  • 话虽如此,我认为即使你只有一个微服务,你也不能保证这样的一致性,因为为了弹性和高可用性,你可能需要通过至少2个实例来扩展它。如果出于某种原因,您可以负担得起一个服务的单个实例,那么您可以将此单个服务设置为唯一的写入器,并在应用程序级别应用一些线程同步。

如果我最初的假设是错误的,请忽略以上所有。

最新更新