0

我正在使用下面提到的 MYSQL 过程(未提及的确切参数)将数据插入三个表“T1”、“T2”和“T3”中。

CREATE DEFINER=`root`@`%` PROCEDURE `insert_values`(v1,v2,v3,v4,v5,v6.......)
begin
declare max_id bigint;
start transaction;
insert ignore into T1
fields(.....)
values
(v1,v2,v3,.......);
insert ignore into T2
fields(......)
values
(v1,v4,..........);
If (v3 <> '') Then
    set @max_id:=(select max(id) from T1); 
    insert ignore into T3
    fields(.......)
    values
    (@max_id,v3,v5,v6,........);
End If;
commit;
end

在表 T1 和 T2 中,字段“id”是自动递增的主键,因此不会通过过程插入。在此过程中,我首先在表 T1 和 T2 中插入数据,然后从表 T1 中的变量“max_id”中读取最大“id”(最后插入/自动递增的“id”),该变量由“插入忽略”自动生成T1....." 查询此程序。

我通过使用多线程的 java 代码调用此过程。

我的问题是语句“set @max_id:=(select max(id) from T1);” 有时不是读取此会话/线程的“插入忽略到 T1 .....”查询生成的最后一个自动增量值,而是读取错误的值(因为可能是另一个并行线程正在将其数据插入表中在当前线程从 T1 读取“max_id”之前的 T1,因此“max_id”正在获取由另一个线程递增的值)。

那么如何解决这个问题呢?改变隔离级别可以解决吗?

这些表使用 INNODB 存储引擎。

“@@GLOBAL.tx_isolation”是“可重复阅读”

“@@tx_isolation”是“可重复阅读”

“@@autocommit”是“1”

感谢和问候

4

1 回答 1

1

Have you tried using LAST_INSERT_ID()?

...
insert ignore into T1
fields(.....)
values
(v1,v2,v3,.......);
/* SET @max_id := LAST_INSERT_ID(); */
SET max_id := LAST_INSERT_ID();
...
insert ignore into T3
fields(.......)
values
(max_id,v3,v5,v6,........);
...

UPDATE

It is important to indicate the difference between 9.4. User-Defined Variables (@max_id) and 13.6.4.1. Local Variable Syntax DECLARE (max_id), are different variables. In this case better to use (max_id) local variable.

于 2013-10-10T14:49:28.110 回答