公交司机解决PSQLException
2013-10-31 13:36
197 查看
最近遇到了一个bug,是关于JPA语句的问题,其实代码很简单,就是使用NamedQuery对数据库中符合条件的数据进行更新操作,代码如下(其实不想贴代码)
(在车上拍的,当时算了一下,不禁心中一惊)
@NamedQuery(name = "customer.updateSentToBusinessCheckByCustomerIds", query = "update Customer as c set c.sentToBusinessCheck = true where c.id in :customerIds")})很简单就是in 后面传递一个list的参数,根据这个list当中的数值进行条件更新,因为数据量小的时候比如几百、几千还是没有问题的,但是一旦list中的数据变大之后,准确的说是超过三万多就不行了(你知道为什么是三万多吗,或者这么问你知道为什么数值是32767吗),生产上我们这里的list是五万多记录,于是会报如下错误(其实真的不想贴代码):
Internal Exception: org.postgresql.util.PSQLException: An I/O error occured while sending to the backend. Error Code: 0 Call: UPDATE CUSTOMER SET SENTTOBUSINESSCHECK = ?, ENTITYVERSION = (ENTITYVERSION + ?) WHERE (ID IN (?,?,?,?,?,?,?,?,?,?......)bind => [60102 parameters bound]最快速的解决问题的办法——Google(你知道为啥不用百度吗?),从网上找到一篇文章(轻击这里)重点引用如下。(请注意,具体的解决办法不重要,重要的是作者解决问题的思路和行动意识。) Not a very concrete message, right? When I first saw this exception I waskind of baffled and disaffected. But after narrowing down the problem in adebug session and looking at the PostgreSQL JDBCdriver’s source code the cause was obvious: the PostgreSQLclient/backend protocol dictates that the number of parameters be send from theclient to the Postgres backend as a 2 byte integer (aaah, now the above message actually makes sense). You’llfind details of the protocol here if you’re brave (my 2-byte friend is definedin the Parse message). 这下明白了,出现异常的原始是因为JPA实现的时候允许的最大的参数数目是有上限的(废话~)。文章最后也说了解决办法,一旦当参数超过上限这个时候就应该把参数分别传递,在这里就是将list分别传递到JPA语句中进行更新操作。最终代码如下(真的,真的不想贴代码)
...... emMain.createNamedQuery("customer.updateSentToBusinessCheckByCustomerIds").setParameter("customerIds",customerIds); int size=customerIds.size(); if(size>30000){ List<Long> customerIdsSplit=new ArrayList<Long>(); for(int i=0;i<size;i++){ customerIdsSplit.add(customerIds.get(i)); if(customerIdsSplit.size()==30000){ updateList(customerIdsSplit); customerIdsSplit.clear(); } } updateList(customerIdsSplit); }else{ updateList(customerIds); } ...... private void updateList(List<Long> customerIdsSplit) { Query query = emMain.createNamedQuery("customer.updateSentToBusinessCheckByCustomerIds") .setParameter("customerIds",customerIdsSplit); query.executeUpdate(); }关于解决问题的东西到此结束了,但是以上都不是本文的重点,有几点感触比较深刻的。1. 那篇博客自己很喜欢,代码很少重在思路。2. 看源码,是90%问题的解决之道,前提是时间允许。3. 一切有因有果(这里指那三万多这个数字是有他的来头的)。后记都说程序员,或者软件行业是是需要高智商的,我不这么认为,论据如下:解决完这个问题之后想起来每天都能听到公交车司机咆哮的那句话,“上不去的乘客等下一辆吧!后面跟着一辆呢!!后面的那辆马上就到了!!!”这不就是人太多坐不下然后就需要分批运送么,和上面的问题解决思路是一样的啊!如此可见公交车司机和程序员(或者说工程师)的职位对智商要求是一样的。最后的最后,附图一张聊表心意。
(在车上拍的,当时算了一下,不禁心中一惊)
相关文章推荐
- 公交司机掉头接下错站女童:我明白一个孩子对于一个家庭意味着什么
- 台北县公交司机昏死前紧急停车挽救乘客(图)
- 【图文】公交司机曝黑幕被打成重伤
- 两度刁难小学生 海口一公交司机被投诉遭解聘
- 赣州“冷漠公交”摔死人 司机未停留自顾去吃饭
- 男子手持高尔夫球杆打公交司机(组图)
- webview打开百度生活服务、百度公交出现的错误解决
- 车上有贼公交司机还开门 放走小偷该不该赔?
- 成都上万公交司机重新审查资格
- 关于公交系统中运用NFC-TSM技术进行移动支付的解决案例浅析
- 公交智能化是解决城市公共交通的问题的利器
- 又是公交司机不愿免费载老人?乘客愤而投诉
- 公交司机的智慧--绝对强悍!
- 见识美国公交司机
- 奔驰司机持高尔夫球杆打公交司机续:已被停职
- 公交司机脚下热浪烫爆温度计
- 25路公交司机被赞"英语达人" 每天160次双语报站
- 广州:开通小公交 解决大问题
- 月薪从1300提到2000多 公交招司机十人抢一岗
- 此文 献给一位卓越的公交司机