如何避免Race Condition通过微服务容器更新sql记录插入/更新

我正在使用微服务架构,使用consul进行服务发现,使用ECS来维护docker容器

现在我正在开发一个微服务,它将从AWS SQS读取记录,经过一些验证后,它将被插入到SQL中。

问题对于可伸缩性,假设我们启动了两个容器A和B,并且如果A和B都尝试更新SQL上的相同记录,那么我该如何管理隔离并避免竞争条件

一个不确定的解决方案我认为可以在Elasticache上提供一些令牌服务

但是,如果有人可以分享他在这种用例上工作的经过验证的解决方案,那将不胜感激

1
投票

我假设您的意思是在SQL RDS上通过SQL来管理SQLServer,它与任何其他SQLServer实例没有区别。而且您的问题与微服务或AWS无关。如果从多个不同实例访问同一数据源,则会出现争用情况。在SQL Server中有两种不同的方法来处理此问题:

悲观锁定 乐观锁定

您可以根据您的方案选择两个选项中的一个。更多信息here

在悲观锁定中,当您通过SELECT命令读取行时锁定该行。您应该使用READ COMMITTED隔离级别或在查询中明确指定LOCK hint。

对于乐观锁定,您可以在表中定义一个列,每次更新列时都会更改该列:

UPDATE RaceTable SET UpdatedOn = @currentDate WHERE Id = @id AND UpdatedOn = @lastUpdateDate

有关SQLServer中并发控制的更多信息:

https://technet.microsoft.com/en-us/library/ms189132(v=sql.105).aspx https://docs.microsoft.com/en-us/sql/t-sql/statements/set-transaction-isolation-level-transact-sql https://technet.microsoft.com/en-us/library/ms175519(v=sql.105).aspx

尽管如此,由于您提到了微服务架构,我建议您为每个服务创建单独的数据库,并通过API调用(最好是REST)来传达您的服务。更多阅读:https://plainoldobjects.com/2015/09/02/does-each-microservice-really-need-its-own-database-2/