Mysql 批处理调用过程中的重复条目
我有一个基本上如下所示的存储过程:Mysql 批处理调用过程中的重复条目,mysql,google-app-engine,google-cloud-sql,Mysql,Google App Engine,Google Cloud Sql,我有一个基本上如下所示的存储过程: do_insert (IN in_x varchar(64), IN in_y varchar(64)) BEGIN declare v_x int(20) unsigned default -1; declare v_y int(20) unsigned default -1; select x into v_x from xs where x_col = in
do_insert (IN in_x varchar(64), IN in_y varchar(64))
BEGIN
declare v_x int(20) unsigned default -1;
declare v_y int(20) unsigned default -1;
select x into v_x from xs where x_col = in_x;
if v_x = 0
then
insert into xs (x_col) values(in_x);
select x into v_x from xs where x_col = in_x;
end if;
select y into v_y from ys where y_col = in_y;
if v_y = 0
then
insert into ys (y_col) values(in_y);
select y into v_y from ys where y_col = in_y;
end if;
insert ignore into unique_table (xId, yId) values(v_x, v_y);
END
基本上,我会查看是否已经在各自的表中定义了varchar,如果已经定义了varchar,我会选择id。如果没有,我会创建它们并获取它们的id。然后我将它们插入到unique_表中
忽略它们是否已经存在。(是的,我可能会在这里加入更多的逻辑,不必做最后的插入,但这不应该是一个问题。)
我遇到的问题是,当我使用googlecloudsql在批处理JDBC语句中运行该语句时,我会在xs
表中插入重复的条目。下次运行此存储过程时,我会遇到以下异常:
java.sql.SQLException: Result consisted of more than one row Query: call do_insert(:x, :y)
因此,我认为正在发生的是,在同一批语句中发生了两个具有相同in_x
值的调用。这两个调用是并行运行的,两个选择都返回0,因为它是一个新条目,然后它们都执行插入。然后,下一次运行失败
问题:
- 我如何防止这种情况
- 我是否应该将我的select(和可能的insert)调用包装到该表的
锁表中
- 我从未在本地MySQL上注意到这一点,这是谷歌云SQL特有的吗?或者只是侥幸我没有在本地MySQL上看到它
尝试将“insert into xs”语句更改为“insert ignore”,并在列上添加一个唯一的索引。好的,所以我尝试添加锁,但出现了错误:
错误1314(0A000):存储过程中不允许使用锁
那么现在呢?这是一个非常巧妙的解决方法。甚至可能不是一个解决办法,因为它利用了RDBs提供的约束功能。