Mysql 查询写入时对表级所的疑问

2023-02-03 10:23:14 +08:00
 s609926202

业务:第三方回调,同时会 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;");
}
1121 次点击
所在节点    MySQL
6 条回复
opengps
2023-02-03 10:46:27 +08:00
注意:同时会 post 多条过来,假设是 AB 等多条
那就意味着,A 的 fun2 完了,但是 B 的 fun2 还没开始。锁表却是个全局的,部分你 ABC 。。。。
xuxixk
2023-02-03 10:56:10 +08:00
防重复插入就用唯一索引,不要自创别的方法
s609926202
2023-02-03 11:02:09 +08:00
@xuxixk 设置唯一索引会报错,假设 AB 同时进来,A 已经 create 数据了,B 也会 create 数据,B 就会报索引唯一错误。
ttwxdly
2023-02-03 11:48:15 +08:00
一楼说得对。
lookStupiToForce
2023-02-03 12:05:33 +08:00
一楼说得对。
唯一索引报错就报错啊,你处理一下不报错就成了啊
hhjswf
2023-02-03 17:36:51 +08:00
op 不用唯一索引的意思,我想大概是不希望接口出现重复异常,让人觉得程序有问题不够健壮😂如果性能要求不高,尝试分布式锁,把请求串行化

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/912792

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX