业务:第三方回调,同时会 post 多条过来,为防重复插入,加事务表级锁。
假设有表如下:a, b, c
处理函数如下。结果在查表 c 时,报错 1100 Table 'c' was not locked with LOCK TABLES
,事务不是在 fun2 里就已经处理完毕了吗,为何还会出现这个提示?
function fun()
{
if (xxx) {
fun2();
}
// 查表 c
$db->query("select * from c");
}
// 事务查询,表级锁
function fun2()
{
$db->startTrans();
$db->execute("LOCK TABLE a WRITE, b WRITE, c READ;");
$db->query("select * from a");
$db->query("select * from b");
$db->execute("update a set name = 'xx' where ...");
$db->commit();
$db->execute("UNLOCK TABLES;");
}
1
opengps 2023-02-03 10:46:27 +08:00
注意:同时会 post 多条过来,假设是 AB 等多条
那就意味着,A 的 fun2 完了,但是 B 的 fun2 还没开始。锁表却是个全局的,部分你 ABC 。。。。 |
2
xuxixk 2023-02-03 10:56:10 +08:00
防重复插入就用唯一索引,不要自创别的方法
|
3
s609926202 OP @xuxixk 设置唯一索引会报错,假设 AB 同时进来,A 已经 create 数据了,B 也会 create 数据,B 就会报索引唯一错误。
|
4
ttwxdly 2023-02-03 11:48:15 +08:00
一楼说得对。
|
5
lookStupiToForce 2023-02-03 12:05:33 +08:00
一楼说得对。
唯一索引报错就报错啊,你处理一下不报错就成了啊 |
6
hhjswf 2023-02-03 17:36:51 +08:00 via Android
op 不用唯一索引的意思,我想大概是不希望接口出现重复异常,让人觉得程序有问题不够健壮😂如果性能要求不高,尝试分布式锁,把请求串行化
|