MySQL:并发更新(通过线程)在一个简单的 table

MySQL: Concurrent updates (through threads) on a simple table

在我的应用程序中 (VC++/Windows 8) 我有 7 个线程,每个线程都打开了与 MySQL 数据库的连接。所有这些线程同时尝试增加 table 中单个字段的值。

为此,我创建了一个示例 table DEMO_TABLE,其中包含列 MyIndexMyCounter(均为整数),并向其中添加了一行 MyIndex 字段值 0。然后我使用 MySQL Connector C++ :

通过每个线程调用 executeUpdate
executeUpdate("UPDATE DEMO_TABLE SET MyCounter = (MyCounter + 1) WHERE MyIndex = 0");

这里我没有使用任何锁定(行或 table 锁)代码仍然没有给我任何错误或异常。当我检查 MyCounter 的值时,我看到它增加了。所以这似乎工作正常。

但是给我提出了这些问题:

  1. 默认MySQL使用需要锁定table的MyISAM引擎来执行并发更新查询。但是我这里没有加锁table,请问这段代码是如何工作的,不会抛出任何异常呢?

  2. executeUpdate 是否隐式使用任何锁?

(据我所知,InnoDB 提供了我计划在我的代码中使用的行级锁定机制。但在此之前,我只是想自己尝试没有任何锁定的默认引擎会发生什么。我期待我会得到一些异常,它会告诉我有关竞争条件的信息,以便我可以验证使用锁时不会发生同样的情况)

锁定是隐式的,是的,但 executeUpdate() 并没有这样做。 MySQL 中的存储引擎处理锁定和解锁。

任何时候你写入 MyISAM table,你的查询等待 table 上的写锁可用,获取写锁,写完成,写锁被释放。在 MyISAM 中没有真正的写并发,因为每个工作者实际上都在排队等待写锁。您不会收到错误消息,因为写入请求已序列化。

InnoDB 的情况类似但非常不同,因为 InnoDB 仅锁定 table 的一部分,通常在行级别,InnoDB 可以锁定索引内的范围,从而锁定行在指数的那个范围内(以及它们之前的差距)。这种锁定比 table 锁定更精细,允许改进并发行为,但在同一行上没有并发操作——每个工作人员等待它需要的一个或多个锁。

在这两种情况下,锁都是隐式获取的。