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

MySQL:简单表上的并发更新(通过线程),mysql,multithreading,innodb,myisam,mysql-connector,Mysql,Multithreading,Innodb,Myisam,Mysql Connector,在我的应用程序(VC++/Windows8)中,我有7个线程,每个线程都打开了到MySQL数据库的连接。所有这些线程同时尝试增加表中单个字段的值 为此,我创建了一个示例表DEMO_table,其中包含列MyIndex和MyCounter(两个整数),并添加了一行,其中包含MyIndex字段值0。然后我调用MySQL连接器C++: > ExcUTEXUPDATE > 这里我没有使用任何锁(行锁或表锁),但是代码没有给我任何错误或异常。当我检查MyCounter的值时,我看到它增加了。所以这似乎是

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

为此,我创建了一个示例表DEMO_table,其中包含列
MyIndex
MyCounter
(两个整数),并添加了一行,其中包含
MyIndex
字段值0。然后我调用MySQL连接器C++:<代码> > ExcUTEXUPDATE <代码> > 这里我没有使用任何锁(行锁或表锁),但是代码没有给我任何错误或异常。当我检查
MyCounter
的值时,我看到它增加了。所以这似乎是正确的

但我提出了以下问题:

  • 默认情况下,MySQL使用MyISAM引擎,它需要为并发更新查询执行锁定表。但我并没有在这里锁定表,这段代码如何在不引发任何异常的情况下工作

  • executeUpdate是否隐式使用任何锁


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

    锁定是隐式的,是的,但它不是由
    executeUpdate()
    完成的。MySQL中的存储引擎处理锁定和解锁

    每当您写入MyISAM表时,您的查询都会等待该表上的写锁可用、获取写锁、完成写操作并释放写锁。MyISAM中没有真正的写并发,因为每个工作进程实际上都在排队等待写锁。不会出现错误,因为写入请求已序列化

    InnoDB的情况类似但非常不同,因为InnoDB只锁定表的一部分,通常在行级别,InnoDB可以锁定索引中的一个范围,从而锁定索引中该范围内的行(以及它们前面的间隙)。这种锁定比表锁定更细粒度,允许改进并发行为,但在同一行上没有并发操作——每个工作进程都等待它需要的一个或多个锁


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

    非常感谢。这可以清除大部分空气。但是我想知道为什么他们提供了
    SELECT。。。对于更新
    选择。。。锁定共享模式
    查询?隐式锁处理行级锁,应用程序无需担心。那么在什么情况下应用程序需要发出这些查询呢?
    SELECT
    的这些变体是针对InnoDB的;例如,在一个事务中,您需要读取一条记录,进行一些计算,然后更新同一条记录,而不需要任何其他连接潜入并干扰它。在MyISAM中,您已手动使用
    锁表。。。编写
    以获得相同的效果。您的示例是对列进行原子更新。自动锁定(由MyISAM或InnoDB实现)就足以支持这条语句了。明白了!非常感谢:)
    executeUpdate("UPDATE DEMO_TABLE SET MyCounter = (MyCounter + 1) WHERE MyIndex = 0");