MySQL:简单表上的并发更新(通过线程)

时间:2015-05-29 10:31:24

标签: mysql multithreading innodb myisam mysql-connector

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

为此,我创建了一个包含MyIndexMyCounter列(两个整数)的示例表DEMO_TABLE,并为其添加了一行MyIndex字段值为0.然后我就是使用 MySQL Connector C ++

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

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

但是我提出了这些问题:

  1. 默认情况下,MySQL使用MyISAM引擎,该引擎需要锁定表以执行并发更新查询。但我不是在这里锁定表,这段代码如何工作而不抛出任何异常?

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

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

1 个答案:

答案 0 :(得分:1)

锁定是隐含的,是的,但executeUpdate()没有完成。 MySQL中的存储引擎处理锁定和解锁。

每当您写入MyISAM表时,您的查询都会等待表上的写锁定可用,获取写锁定,写入完成以及释放写入锁定。 MyISAM中没有真正的写并发,因为每个worker实际上都在排队等待写锁定。您没有收到错误,因为写请求已被序列化。

InnoDB的情况类似但非常不同,因为InnoDB只锁定表的一部分,通常在行级别,InnoDB可以锁定索引中的范围,从而锁定索引中该范围的行(以及它们之前的差距)。此锁定比表锁定更精细,允许改进的并发行为,但同一行上没有并发操作 - 每个工作程序等待它所需的锁定或锁定。

在这两种情况下,隐式采取锁定。