与 mysql 和多个并发连接的写后读一致性

Read after write consistency with mysql and multiple concurrent connections

我正在尝试了解是否可以实现以下目标:

我有多个应用程序服务器实例 运行 在循环负载平衡器后面。客户端在 POST/PUT 语义之后期望 GET,特别是客户端将发出 POST 请求,等待响应并立即发出 GET 请求,期望响应反映 POST 所做的更改] 请求,例如:

> Request:  POST /some/endpoint
< Response: 201 CREATED
<           Location: /some/endpoint/123
> Request:  GET /some/endpoint/123
< Response must not be 404 Not Found

不保证两个请求都由同一个应用服务器处理。每个应用程序服务器都有一个到数据库的连接池。每个请求都会在响应客户端之前提交一个事务。

因此,数据库将在一个连接上看到一个 INSERT 语句,然后是一个 COMMIT。另一个连接,它将看到一个 SELECT 语句。在时间上,SELECT 将严格在提交之后,但是可能只有毫秒级的微小延迟。

我心目中的应用服务器使用Java、Spring和Hibernate。该数据库是 MySQL 5.7.11,由 Amazon RDS 在多可用区设置中管理。

我正在尝试了解是否可以实现此行为以及如何实现。有一个 similar question,但建议锁定 table 的答案似乎不适合必须处理并发请求的应用程序。

在一般情况下,您不会对这一系列请求有任何问题,因为您的 MySQL 将在 201 响应发回时将更改提交到数据库。因此,任何后续语句都将看到创建/更新的记录。

后续select找不到更新/插入记录的特殊情况是什么?

  1. 另一个进程提交更改或删除给定记录的更新或删除语句。您对此无能为力,因为这是正常操作的一部分。如果你不希望这样的事情发生,那么你必须实现应用程序级别的数据锁定。

  2. 后续的 GET 请求不仅被路由到不同的应用服务器,而且该应用服务器使用(或被迫使用)不同的数据库实例,该数据库实例没有最新状态记录。如果应用程序或数据库服务器级别出现严重故障,或者请求路由非常糟糕(路由到不同地理位置的数据中心),我会设想这种情况会发生。这些不应该发生得太频繁。

如果您使用的是 MyISAM 表,您可能会看到 'concurrent inserts' 的效果(请参阅 mysql 手册中的 8.11.3)。您可以通过将 concurrent_insert 系统变量设置为 0 或在 INSERT 上使用 HIGH_PRIORITY 关键字来避免它们。