在我的应用程序(VC++/Windows 8)中,我有7个线程每个都打开了连接到MySQL数据库。所有这些线程同时尝试增加表中单个字段的值。MySQL:简单表上的并发更新(通过线程)
要做到这一点,我已经创建有列MyIndex
和MyCounter
(均为整数)示例表DEMO_TABLE并加入一排有MyIndex
字段值0。然后,我通过使用MySQL连接C++每个线程调用executeUpdate
:
executeUpdate("UPDATE DEMO_TABLE SET MyCounter = (MyCounter + 1) WHERE MyIndex = 0");
这里我没有使用任何锁定(行或表锁)仍然代码没有给我任何错误或例外。当我检查MyCounter
的值时,我看到它增加了。所以这似乎是正确的。
但已经提出了我这些问题:
默认情况下,MySQL使用它需要锁定表并发更新查询执行MyISAM引擎。但是我没有在这里锁表,这个代码如何工作而不会抛出任何异常?
executeUpdate是否隐式使用任何锁?
(按我的知识InnoDB提供行级锁定机制,我计划在我的代码使用。但在此之前,我只是想对我自己尝试用默认的引擎发生了什么,没有任何锁。我期待我会得到一些异常,这将告诉我有关竞态条件,以便我可以验证相同情况不会发生与使用锁定)
非常感谢。这清除了大部分空气。但我想知道他们为什么提供了'SELECT ... FOR UPDATE'和'SELECT ... LOCK IN SHARE MODE'查询?隐式锁定可以在不需要应用程序的情况下管理行级别的锁,不必担心它。那么在什么情况下应用程序需要发布这些查询呢? – Atul
'SELECT'的这些变体适用于InnoDB;例如,它们用于需要读取记录的事务中,进行一些计算,然后更新相同的记录,而不会有任何其他连接偷偷摸摸并且弄乱它。在MyISAM中,您已经手动使用'LOCK TABLE ... WRITE'来获得相同的效果。 –
你的例子是一个原子'UPDATE'递增列。自动锁定(通过MyISAM或InnoDB)对于_single_语句已足够。 –