在InnoDB MySQL存储引擎中,正在使用存储过程生成tbaaa000000
形式的主键值。
因此,主键的格式是:
对于固定长度说l
,第一个two
字符表示table_name,下一个m
表示字母,其余(l-2-m
)表示数字(仅限数字)。
已对存储过程进行编码,以使用动态SQL手动增加最右边的m+n
个字符块。这是通过查找表中存在的最大ID(比如tbaaa999999
)并将其递增(到tbaab000000
)来完成的。通过动态SQL,我的意思是它已经被用于在运行时通过在查询中包含变量来动态地构建SQL语句。
让我们假设我们正在尝试为表Table1
生成此主键。另外,我们还有另一个表(例如Table2
),它引用了Table1
的主键(Table2
在Table1
上有一个外键)。
现在,使用PHP脚本将表单提交到服务器,该脚本将表单数据插入Table1
和Table2
。但是,在执行Table1
的查询期间,使用存储过程生成了主键ID,但是即使对于Table2
的插入查询,也会同时需要此ID。 PHP脚本。
此外,可能有多个客户端尝试访问该页面,因此PHP脚本会为所有用户运行,因此生成存储过程可能会为多个用户生成相同的主键ID。
Table1
中管理仅生成和插入唯一ID?Table2
?SO鼓励我把我尝试过的东西包括在内,所以我已经把我的努力包括在内了。但是,我不希望答案的范围受到限制,所以请在阅读我的试用版之前尝试一种方法。
我们可以从PHP脚本调用一个过程,该过程将插入数据作为参数,并生成Table1
的主键ID,并将数据插入到两个表中。但是,这会失败,因为整个过程仍然可以为并发请求生成相同的ID。
我还在PHP脚本端探索了一个try-catch
方法,该方法将调用一个函数来生成并将ID返回给PHP脚本。然后,这将尝试插入Table1
,如果已经存在相同的ID,则会失败(可能是由于并发另一个用户的另一个插入处理)并抛出duplicate key exception
并再次尝试生成,从而给出唯一性。但是,我不确定这种方法,因为这可能效率低下,可能会引起性能问题。
答案 0 :(得分:1)
这是交易的目的。您需要做的伪代码是:
如果另一个客户端在发生这种情况时尝试访问表1,它们将被阻止,直到提交事务为止。