我有一个lambda函数,它从消息队列中接收新注册用户的数据,然后将该数据插入两个不同的数据库中.

这两个数据库属于两个不同的微服务.第一用户服务使用RDS Postgres,第二管理服务的数据库基本上是单个DynamoDB表.

I want to achieve "all or nothing" behavior for data insertions in the two databases - either insertion in both succeeds or both fails.

  • 我怎样才能有一种"原子事务"来插入两个数据库,实现"全有或全无"的行为?
  • 如果数据被插入到管理服务的DynamoDB表中,但由于某种原因无法插入到用户服务的Postgres表中--我该如何在DyanamoDB中回滚插入操作呢?

我可能会在代码级实现这种功能,但如果假设我在5个而不是2个不同的数据库中插入了"全有或全无",那么代码将会非常混乱.

我想知道当涉及到与不同的DB交互时,是否有一些标准的方法来实现类似原子事务的行为.

推荐答案

基本上,你需要distributed transaction,这实际上是一个相当复杂的问题.一种流行的方法是使用two-phase commit protocol(2PC),它使用transaction manager/coordinator(可能成为单点故障).我不知道AWS是否提供了一些开箱即用的东西,可以协调不同DB之间的分布式事务,所以如果你要走这条路,你可能需要实现一个(据我所知,DynamoDB和RDS PostgreSQL都支持2PC).

在微服务体系 struct 中,由于潜在的性能成本,使用分布式事务的情况相对较少.更常见的方法是"切换"到eventual consistency,并使用例如saga pattern这样的东西:

传奇是一系列本地交易.每个本地事务更新数据库并发布消息或事件以触发SAGA中的下一个本地事务.如果本地事务因违反业务规则而失败,则SAGA执行一系列补偿事务,这些事务undo撤消前面的本地事务所做的更改.

例如,在AWS中,您可以实现saga orchestration pattern with step functions.

Database相关问答推荐

触发器作为完整性的判断约束

如何使授权服务器与外部数据库保持同步?

动态数据模型

术语 SSTable 和 LSM Tree 有什么区别

Spring DriverManagerDataSource vs apache BasicDataSource

如何使用错误消息中指定的 tbspaceid tableid 在 DB2 中查找表和列

502 是数据库错误的适当状态代码吗?

在 MySQL 中实现一对一关系时确定外键

ER图中的一对多关系

在数据库中存储枚举值的最佳方式 - String 或 Int

行之间的 SQL 差异

如何使用 INSERT ... ON CONFLICT ... 更新所有列?

主键和主属性有什么区别?

此平台不支持 LocalDB

我应该如何使用 MySQL 构建我的设置表?

如何将sqlite表从磁盘数据库复制到python中的内存数据库?

使用批处理文件执行一组 SQL 查询?

为什么 OODBMS 不像 RDBMS 那样普遍?

如何使用 PL/SQL Developer 连接到远程 Oracle DB?

清空数据库是什么意思?