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上看到它

我还没有测试过,但我猜batch语句引入了某种程度的并行性。因此,“select x into v_x”语句可以与“insert into vx”语句竞争,后者可以执行多次


尝试将“insert into xs”语句更改为“insert ignore”,并在列上添加一个唯一的索引。

好的,所以我尝试添加锁,但出现了错误:
错误1314(0A000):存储过程中不允许使用锁
那么现在呢?这是一个非常巧妙的解决方法。甚至可能不是一个解决办法,因为它利用了RDBs提供的约束功能。