如何在关联的3张及以上表中执行插入?并发场景相关疑问
关联表单事务插入问题解答
疑问1:当前使用的查询是否为最优方案?
绝对不是最优方案。如果你的当前方案是通过查询MAX(entPatID)再加1来生成新ID,这种做法存在两个核心问题:
- 性能差:每次查询MAX值都需要扫描全表(无索引时性能损耗更明显),数据量越大效率越低;
- 并发风险高:这也是第二个疑问的核心根源,完全不适合多用户并发场景。
最优方案是利用数据库原生的会话级自增ID获取函数,比如MySQL的1081418、SQL Server的SCOPE_IDENTITY()、PostgreSQL的RETURNING子句。这类函数只会返回当前会话中最后一次插入操作生成的自增ID,既不需要全表扫描,又能保证会话隔离性。
以MySQL为例,单事务插入三张表的正确写法如下:
START TRANSACTION; -- 插入entities并获取其自增ID INSERT INTO entities (字段1, 字段2) VALUES ('值1', '值2'); SET @entity_id = 1081418; -- 插入entities_pattern,关联entities的ID,并获取自身自增ID INSERT INTO entities_pattern (entity_id, 字段3) VALUES (@entity_id, '值3'); SET @entPatID = 1081418; -- 插入stock_room,关联entities_pattern的ID INSERT INTO stock_room (entPatID, 字段4) VALUES (@entPatID, '值4'); COMMIT;
疑问2:多用户并发插入时,@lastID+1能否保证获取正确的entPatID?
完全不能保证。
当多用户并发操作时,多个会话可能同时执行SELECT MAX(entPatID) FROM entities_pattern,此时它们会拿到相同的最大值,各自加1后生成的新ID会重复,直接导致主键冲突或关联数据错误——这是典型的竞态条件问题。
而使用数据库提供的会话级自增ID函数时,每个会话只能获取自己插入生成的ID,完全不受其他会话的插入操作干扰,在单事务中能100%保证关联ID的正确性。
内容的提问来源于stack exchange,提问作者babak-maziar
相关产品推荐
相关产品推荐

