事务内插入同主键数据:并发线程的冲突触发时机与执行逻辑
事务插入与主键冲突的问题解答
第一个问题:事务内插入相同主键的数据是否会阻止其他线程插入?
这取决于数据库的锁机制和隔离级别,以常用的InnoDB为例:
- 当第一个线程在事务内完成相同主键的插入操作后,会对该主键对应的行加排他锁,此时其他线程尝试插入相同主键的数据时会被阻塞,直到第一个事务提交或回滚。
- 如果第一个事务提交,被阻塞的线程会立即抛出主键冲突错误;如果第一个事务回滚,被阻塞的线程就能成功完成插入。
第二个问题:同key并发调用exampleFunc的行为分析
先看你的代码逻辑:
public void exampleFunc(int key) { db_connection.start_transaction(); db_connection.execute("INSERT INTO table (pk, content) VALUES ({key}, 'placeholder')"); // Run some other code db_connection.execute("UPDATE table set content = 'Final value' where pk = {key}"); db_connection.commit(); }
当两个线程用同一个key调用这个函数时:
- 先抢到锁的线程(线程A)会成功执行
INSERT语句,之后正常运行中间的「Run some other code」,接着完成UPDATE和commit操作。 - 另一个线程(线程B)在执行
INSERT语句时会被阻塞,根本没机会执行中间的代码。 - 等线程A提交事务后,线程B的
INSERT会立刻触发主键冲突错误,后续的UPDATE和commit都不会执行。
如果使用的是不支持行级锁和事务锁的数据库(比如MyISAM),线程B的INSERT会在执行时直接抛出主键冲突错误,同样无法执行中间代码。
内容的提问来源于stack exchange,提问作者Faceplanted
相关产品推荐
相关产品推荐

