事情的经过是这样的:
一个夏日的午后,我在啪啪啪的敲代码,正爽着呢,老大在背后拍了拍我的肩膀,说让我写个功能。
我说啥功能,他说:“operate 模块那边每次收到文件都会给你发一条消息。然后对消息进行计数,每隔一段时间,你把这个计数写入一次数据库。”
我说为什么。
老大说对文件数量进行计数。
我说为什么不让他们直接去更新数据库。
他说 operate 那边是多线程,数据量比较大的时候,同时更新数据库会出问题。所以需要通过消息队列,把数据都汇总到你这儿,你来统一更新这个数据。
大概意思我听明白了,我说行,我做。
意思应该是这样:operate 那边是多线程处理数据,并且是多个线程共同维护同一个数据库的某个统计字段。在数据更新比较频繁的时候,数据会出现错误。
我猜应该是同步没做好。但是为什么没做好,我不知道,部门多了,产品复杂了,什么情况都可能出现。老大让这么做,那就有他的道理,既然是和其它部门商议后的结果,这个方案肯定就确定了。
和老大商量后,我的工作是这样的:创建一个线程出来,获取数据库中统计字段的当前值,监听发送给我的消息,然后累加这个值,每隔一段时间(暂定5秒)更新一次这个值。
开始写代码的时候在想,为什么要把这个数据取出来,然后再加上一个数字,然后再放回去呢?为什么把更新一个数字的过程分成三个部分呢?这多麻烦啊。我印象中好像在《深入浅出MySQL》这本书里看到过,mysql 中可以写表达式。不过平时没怎么用过,就去一个MySQL的QQ群里咨询了下,网友们都很热情,在逗图和吹牛逼的时候还顺便回答了我这个问题。
如果我们要更新的字段是 sum ,那么就可以直接写“update table_name set sum = sum + 5 where id = 1;”就可以了。然后我 就把这个情况告诉老大了,老大说你测试下这个方式是不是线程安全的,还有测试下多线程下的效率。
我写了个程序,测试了下效率,也查阅了我们使用的MySQL引擎的文档,在我们的开发环境下是线程安全的,效率也让老大看了,他觉得还可以接受。然后,然后他就找 operate 部扯皮去了。
因为这样更新数据,是线程安全的,所以当 operate 模块是多线程的时候,使用这个方式更新数据,就不存在线程同步问题了。也就没必要让我再拉个统计线程出来了。
老大说更新数据库的部分让 operate 来做,operate 的人肯定是不情愿啦。他们说,既然已经这么定了,就得这么做,我们的都快收尾了,你又让我们改这个。
老大说这么做太复杂了,你们直接更新会更简单。他们反问我老大,说:“既然这么做简单,你干嘛一开始要那么搞呢?”。老大愣了两秒钟,很愤怒的说:“当时没人告诉我可以这么做啊!”。
后来两个部门又开了个会,经过一天的扯皮,更新统计数据的部分,成功推给 operate 部去做了。后来我发现, operate 的东西其实并没有收尾。
嗯,故事讲完了,说说我的感受。
首先,在听到老大的愤怒后,我第一个想到的词是,知识储备。
至少从我刚刚经历的这个事情来看,知识储备是非常重要的事。虽然就是一个SQL语句的事儿,可是不知道这个用法的话,就真的会把东西弄复杂了。所以平时没事的时候还真应该多读书,多学习,增加自己的知识储备,指不定在哪天就用到了呢。
第二点就是对事物审慎的态度。
在我告诉老大,我发现了一条真理的时候,他没有让我直接去用,而是让我检验这个真理的安全性和性能如何。
这个也是很重要的。估计要是我的话,直接就用上了,万一真的是性能达不到或者不支持线程安全的话,前面的工作估计也白做了。所以在接触一个新东西的时候,应该先全方位的考察下这个东西是不是真的能解决眼下的问题,并且不会带来新的问题。要是不能的话,那就宁愿不要用。
同步发表于:http://www.fengbohello.top/blog/p/knowledge-reserve