如何处理一次性多个插入操作

4

我需要一次运行多个查询。下面是一个例子。 如果在表A上进行插入并将最后的插入ID存储在变量中,在同时发生另一个插入时,我如何确保正确的值被插入到其他表中?我需要锁定所有表,运行我的查询然后解锁吗?我读到了事务相关的东西。我需要它们吗? 感谢任何建议。

create table a (
id int not null auto_increment primary key,
name varchar(10)
) engine = innodb;

create table b (
id int not null auto_increment primary key,
id_a int
) engine innodb;

create table c (
id int not null auto_increment primary key,
id_a int)
engine innodb;

insert into a (name) values ('something');
set @last_id = last_insert_id();
insert into b (id_a) values (@last_id);
insert into c (id_a) values (@last_id);
3个回答

2

在这个序列中

insert into a (name) values ('something');
set @last_id = last_insert_id();
insert into b (id_a) values (@last_id);
insert into c (id_a) values (@last_id);

变量@last_id是全局的,但仅限于您特定的会话。因此,一旦设置了它,除非再次更改,否则该值不会改变。
至于last_insert_id(),特别是手册中指出:
服务器上维护生成的ID是基于每个连接的。
因此,其他连接的操作无关紧要。对a生成的ID保证用于bc的插入。

嗨,Richard。感谢您的快速回复。因此,通过这些查询,我可以确信即使更多的客户同时在同一张表上插入数据,我编写的软件也不会出现问题。这是个好消息 :) - anfrasa
感谢大家。一旦我有足够的声望,我会给每个人点赞以感谢你们为我所付出的时间。看起来我需要15分。请原谅我。已经达到了分数并履行了承诺 :) - anfrasa
+1 你好 Richard。有趣的线程。如果在第一次插入后出现问题(例如断电或任何其他问题),我将失去数据完整性。如果我错了,请纠正我。为避免这种情况,不需要使用事务吗? - Nicola Cossu
@nick 那是一个有趣的案例。我会担心其他事情,但你是对的,如果在“插入a”和后面之间“失去电源”,它们将被断开连接。我想当这种事情发生时也会有其他需要解决的问题。 - RichardTheKiwi

1
根据MySQL 文档last_insert_id()仅适用于当前会话。

生成的ID是在服务器上以每个连接为基础维护的。这意味着函数返回给特定客户端的值是该客户端最近影响AUTO_INCREMENT列的大多数最新语句生成的第一个AUTO_INCREMENT值。即使其他客户端生成了自己的AUTO_INCREMENT值,该值也不会受到其他客户端的影响。此行为确保每个客户端都可以检索其自己的ID,而无需担心其他客户端的活动,也无需进行锁定或事务。


谢谢Suroot。我需要一些比我更有技巧的人确认一下。 :) - anfrasa

1

嗨,马克。谢谢你的回复。我没有使用任何框架。我正在自己编写一个简单的PHP应用程序,它将在一个小办公室内运行,并由不同的用户填充数据库。根据理查德的答案,我不需要任何事务。 - anfrasa
事务在数据库记录需要同时被多个用户更新并且需要避免冲突时非常有用。我曾经在使用 Oracle 数据库应用程序时使用过事务,其中数据完整性至关重要。我的大多数 Web 应用程序只有少数用户,MySQL 的基本功能已经足够了,所以 Richard 的答案更加适用。 - Marc Audet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接