MySQL事务控制无障碍设计指南
|
跟DBA吵完第三轮的时候,我盯着他工牌挂绳上那道浅白压痕,心想这玩意儿比我们事务隔离级别还难复现——去年十月份,灰度开关没推完,线上库存接口突然开始返回负数,不是超卖,是直接倒扣,像有人拿SQL手电筒往事务缝里照,照见一地碎玻璃。 我原以为是READ COMMITTED下幻读漏网,结果查binlog发现连BEGIN都少打了一个。测试上周刚提的工单,说“订单创建时偶发状态错乱”,我扫了一眼就转给前端:你confirm按钮没禁用吧?他回了个咖啡杯表情包,杯壁印着公司logo,边沿一圈细小划痕。后来才发现,是他调的下游履约服务在commit前调了两次callback,而我们事务里锁的是行,不是意图——意图这种东西,MySQL不认,只认X锁和gap锁,但没人告诉产品什么叫gap。 优胜劣汰?对。淘汰掉那些以为“加个@Transactional就万事大吉”的人,淘汰掉在CR时说“先上线再观察”的PM,淘汰掉监控大屏上那个绿线明明抖了十八毫秒却非说“基线波动正常”的值班同事。我敢打包票:去年十月十七号下午三点零七分,订单号以OXJ开头的三百七十二次调用,全卡在InnoDB的lock_wait_timeout=50上——不是配置错了,是我们自己把update语句写进了循环里,还是foreach遍历SKU再逐条update。DBA甩给我一句:“你们代码里嵌套了几个START TRANSACTION?”我哑火。他手机震了一下,oncall消息弹出来,但他没看,顺手拧开保温杯喝了一口,杯盖内侧结了层薄盐霜。 碎片拼起来就是:事务控制无障碍?无障碍的前提是你别给自己设障。比如,让支付回调进来就直接UPDATE status='paid',也不查当前状态;比如,让运营后台一个导出按钮触发SELECT FOR UPDATE然后睡五秒;比如,把乐观锁version字段更新写成SET version = version + 1 WHERE id = ? AND version = 123,可上游传来的version是字符串"123"——MySQL还真给你转成功了,只是转完变成123.0,下次比对永远失败。这不算bug,算“类型宽容性红利”。红利?红利是DBA凌晨三点给你发的截图,上面一行EXPLAIN显示type=ALL,key=null,rows=428697。
文章配图,仅供参考 前端昨天改了个按钮文案,从“立即下单”改成“马上锁仓”,我盯着Git diff看了两分钟。锁仓?我们连库存都没真正锁住,只锁住了主键值为100234的那行,而SKU关联的仓库、批次、质检状态、跨境报关标识……全是另一张表,另一套锁机制,另一套失效逻辑。谁去倒了杯水?是测试,穿蓝格子衬衫那位,她路过我工位时说了句“你们后端是不是该把分布式事务也管管”,说完就把纸杯放我显示器边上了,杯底水渍洇开一小片,像没提交的脏读痕迹。 无所谓。真无所谓。KPI里早就不写“事务一致性达标率”了,改成“订单履约SLA达成率”,SLA怎么算?只要用户没投诉、客服没建单、日志没ERROR,就算达成。于是我们把XA拆成两段HTTP调用,中间加MQ,叫“最终一致性”;把重试逻辑塞进补偿job,叫“幂等保障”;把锁超时降成2秒,叫“用户体验优先”。产品经理今早站会说“锁仓动作得有反馈动画”,我点头,心里默念:动画三帧之内,我的事务早rollback八回了。 所以别搞什么《指南》。指南是给新人看的,新人三年后还在写try-catch里嵌beginTransaction。真正活下来的,都是靠背锅背出来的肌肉记忆——比如看到where条件带函数,立刻删掉;看到join三张表以上,立刻查执行计划;看到insert into select … limit 1,立刻问DBA这个select走不走索引。我跟DBA吵完最后一轮,他撕了张便签,在背面画了个菱形图:BEGIN → 业务逻辑 → 检查→COMMIT/ROLLBACK。我盯着那图,忽然想起去年十月十六号晚上,运维群里有人问“canal消费延迟涨到两小时了咋办”,没人答,因为那天我们刚把所有事务里的sleep(100)注释取消了——说是压测需要,其实是怕并发太低,测不出死锁。 我建议你明天上午十点,去生产库执行一次SELECT FROM information_schema.INNODB_TRX WHERE TIME_TO_SEC(timediff(now(), trx_started)) > 30;不用改代码,不用推配置,就看看有多少trx_state是'LOCK WAIT'。咖啡凉了,你喝一口,顺便数数自己有几个事务还在等锁。要是超过七个……别修,先备份好binlog,然后找DBA,带上那张印着公司logo的纸杯,杯沿朝上,表示诚恳。至于“无障碍”?等哪天开发自测能跑通跨库转账+退款+补单全流程不卡顿,再说吧。现在?先活过下周三发版。 (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


MySQL高可用入门:告别单点故障,轻松实现自动容灾