在查询执行期间失去连接

时间:2021-06-17 03:55:36

标签: mysql

假设这种情况:

我有一个插入查询,它有一个自动递增键

Insert into xxx Values(0, 1)

如果我调用 mysql_query(&sql, szQuery) 但由于物理网络错误而与服务器的连接丢失会发生什么。

我有这个问题,因为我的项目有一个带有 SQL 的包装器,如果由于 net error 查询失败,我想进行自动重试,这种情况每天都会在实际环境中发生,称为 net flash disconnect and reconnect。

有时候,客户端并没有得到查询结果,但是服务器已经完成了插入查询。在这种情况下,如何在客户端和服务器之间同步状态?

除了主键没有其他唯一的数据,这是一个常见的查询操作,所以在我的项目中,我们想重试插入查询,如果插入查询有预定义的键(如GUID),重试将好的,但是如果主键是自增的,重试操作可能会有两行。

在我的项目中,我们使用自动提交,所以如果插入了一行数据,并且由于网络错误而没有将查询的ack发送到客户端,有没有更好的方法来检查是否需要再次插入以进行自动增量行?

1 个答案:

答案 0 :(得分:0)

<块引用>

如果我调用 mysql_query(&sql, szQuery) 但由于物理网络错误而与服务器的连接丢失会发生什么。

如果您处于显式事务中(在 BEGINSTART TRANSACTION 之后,但在 COMMIT 之前),则语句将因未提交的事务而回滚。

在显式事务之外,将 AUTOCOMMIT 视为包含单个查询的隐式事务。

无论哪种情况,在查询之后测试错误都会让您知道查询是否完成。

<块引用>

在这种情况下,如何在客户端和服务器之间同步状态?

也许这需要从客户端同步,但从服务器端这将是来自新客户端的新的独立连接 - 所以像客户端刚刚启动一样同步。并且您必须了解查询可能尚未提交,因此您不会立即看到查询所做的更改。一段时间后,您可能需要再次刷新数据。

<块引用>

...有没有更好的方法来检查是否需要再次插入自动增量行?

识别发送查询的连接。等到查询完全执行(processlist 显示此连接处于等待或关闭状态)然后检查应插入的数据是否存在于表中。

不要“自动重新连接”(某些 API 中的一个选项)。例如,如果您在自动重新连接启动时通过一个显式 连接,那么您将一团糟。第一部分将被回滚,然后开始一个新的事务。

由于处理 AUTO_INCREMENT 的内容,回滚的 INSERT 可能已经消耗了一个数字。永远不要依赖于没有间隙的ID。