-
背景描述
某日上午生产上突然出现应用无法连接数据库,c3p0错误connect time out,重启应用后依然不见好转,经DBA检查发现存在对某张表的for update,以及其他业务操作对该表的update操作,且这些会话均长时间未释放,查看日志也发现这些sql语句执行时间有些甚至长达100多秒,后通过DBA 手工删除会话,释放连接后系统才恢复正常,导致此事故的是系统的某一个业务功能,但却因为这个不当操作导致系统全线业务瘫痪,由于此前该功能已经运行多日,却未发现异常。
-
代码检查
这里先贴一段代码,由于代码是在前任挖坑离职后,我后面接过来的,大家自行体会。
这段代码目的是先锁住整表,然后查出主键的maxvalue,然后根据规则对maxvalue进行+1 ,然后进行insert操作,在没请求量,不对表做update操作的情况下,单次执行确实是没什么问题,但是问题就在这张表是业务表,是会对数据进行操作的,一旦加上存在并发,哪怕这个并发都不是秒级的,这种操作都是撑不住的,关键!做这个操作的表还不止一张!其中有几张还是比较核心的业务表,每个表的主键都是通过这种方式来搞,当时的感觉就仿佛吃了一口老八秘制小汉堡。
DBA杀掉会话临时解决后,下午又出现了同样的情况,没办法,完全修复需要时间,只能先紧急对sql进行修改 select * from table for update wait 3 ,也就是本次for update 若3s未获得锁,则直接返回资源忙碌,虽然会造成前端的部分请求失败,但至少不会导致系统全线崩溃,然后紧急上线,后未发生同样的情