金蝶云社区的二开最佳实践里,有两条反复被提起,都是踩过事故之后总结的。
第一条:DataSet 循环里别做长时间处理
插件里遍历 DataSet 逐行处理是常见写法。问题在于,DataSet 在遍历期间通常持有数据库连接或结果集游标。循环体里如果做网络请求、文件读写、调用外部接口这类耗时操作,连接就被一直占着。
单用户测试完全看不出来。生产上几十个并发,连接池很快耗尽,表现是整站变慢甚至无响应,日志里看不出明显错误。
正确做法是两段式:先把 DataSet 里的数据读到一个内存集合(List 或数组),关闭结果集,再遍历处理。需要写回的部分收集起来批量提交。
判断标准很简单:循环体里有没有 IO。有,就必须拆开。
第二条:PostgreSQL 关联更新的语法陷阱
金蝶部分产品线跑在 PostgreSQL 上,二开时写关联更新容易踩坑。
MySQL 的习惯写法是 UPDATE A JOIN B ON ... SET A.x = B.y。PostgreSQL 不支持这个语法,标准写法是用 FROM 子句:UPDATE A SET x = B.y FROM B WHERE A.id = B.id。
陷阱在于,如果 WHERE 条件写漏或者写松,比如只写了 A.status = 1 而没写关联条件,结果就是整张表被同一行数据刷掉。这不是报错,是静默地把数据改坏。
更隐蔽的情况是子查询返回多行。看起来是关联更新,实际执行时取了任意一行,结果不可预测。
防护手段
一,任何 UPDATE 或 DELETE 执行前,先用同样的 WHERE 条件跑一次 SELECT COUNT(*),确认影响行数在预期内。
二,在事务里操作,先验证再提交。
三,生产环境禁用不带 WHERE 的 UPDATE 与 DELETE,这条应该做成数据库层面的规则。
这两个坑的共同点
都是“本地测不出来、生产才炸”的类型。本地数据量小、并发低、没人同时操作,三个保护条件在生产全部消失。
所以二开的上线标准不能是“我本地跑通了”,必须是“在接近生产的数据量与并发下验证过”。这条听起来废话,但每次事故复盘都会回到这里。
一句总结
金蝶的二开生态很成熟,社区里能搜到大量案例。动手前先搜一遍,别人踩过的坑没必要再踩一次。
本文由奇幻维度内容助手整理发布,欢迎在评论区交流你的看法。