项目使用jfinal-3.3,部署在阿里云平台。之前使用阿里Mysql,一直很稳定。
可是两周前将Mysql升级为Polardb后,出现一个问题:
使用Model的queryFirst方法根据记录主键查询时,偶尔会返回Null。
1)能确认查询时,记录早已经入库(可能提前几个小时,或几天入库)
2)初步测试结果:Model查询失败后,反复使用Model和Db查询这条记录,Model仍然查不到,Db可稳定查出这条记录。
先看下调试代码:
PayItem payItem = new PayItem().selectPayItemById(joinParty.getPayItemId()); Integer isAudit = payItem==null ? null : payItem.getIsAudit(); JootunLog.error("PayItemNull, transactionId={},payItemId={},payItem={}",transactionId,joinParty.getPayItemId(),payItem); // 重新查询payItem,调试问题,非业务需要: if(payItem==null){ payItem = new PayItem().selectPayItemById(joinParty.getPayItemId()); JootunLog.error("PayItemNull, RETRY 1 transactionId={},payItemId={},payItem={}",transactionId,joinParty.getPayItemId(),payItem); } if(payItem==null){ payItem = new PayItem().set(PayItem.X_ID, joinParty.getPayItemId()).queryFirst(); JootunLog.error("PayItemNull, RETRY 2 transactionId={},payItemId={},payItem={}",transactionId,joinParty.getPayItemId(),payItem); } if(payItem==null){ Record record = Db.findFirst("select * from F_PAY_ITEM t where X_ID=?", joinParty.getPayItemId()); JootunLog.error("PayItemNull, RETRY 3 transactionId={},payItemId={},payItem={}",transactionId,joinParty.getPayItemId(), record); payItem = new PayItem().selectPayItemById(joinParty.getPayItemId()); JootunLog.error("PayItemNull, RETRY 4 transactionId={},payItemId={},payItem={}",transactionId,joinParty.getPayItemId(),payItem); } 出问题时,只有RETRY 3的Db.findFirst能查到结果,其它查询都返回null
public class PayItem extends CoreModel<PayItem> implements Comparator<PayItem>{ // 省略很多代码 /** * PayItem 类 * 根据主键查询收费项 * @param payItemId 收费项id * @return */ public PayItem selectPayItemById(long payItemId){ return new PayItem().setPrimaryValue(payItemId).queryFirst(); } // 省略很多代码 }
public C setPrimaryValue(Object value){ return set(getPrimaryKey(), value); } /** * 返回表的主键字段名 * @return */ public String getPrimaryKey(){ return TableMapping.me().getTable(getClass()).getPrimaryKey()[0]; } @JSONField(serialize=false) public C queryFirst() { Map<String, Object> maps = getAttrs(); List<C> mList = query(maps, ""); return mList!=null && mList.size()>0 ? mList.get(0):null; } public Map<String, Object> getAttrs() { return super._getAttrs(); } public List<C> query(Map<String, Object> maps, String orderBy) { StringBuilder sb = new StringBuilder(); List<Object> values = new ArrayList<Object>(); createSqlAndParam(maps, values, sb, orderBy, false); List<C> list = find(sb.toString(), values.toArray()); return list; } // 简单SQL查询表数据 private void createSqlAndParam(Map<String, Object> maps, List<Object> values, StringBuilder sb,String orderBy, boolean isPage) { checkTableName(); if(isPage){ sb.append(" from ").append(getTableName()).append(" where 1=1 "); }else{ sb.append(" select * from ").append(getTableName()).append(" where 1=1 "); } for(Entry<String,Object> entry:maps.entrySet()){ if(entry.getValue() != null && !entry.getValue().equals("")){ String entryKey = entry.getKey(); if(getLikeColumn().contains(entryKey)){ sb.append(" and ").append(entry.getKey()).append(" like '%"+entry.getValue()+"%' "); }else if(this.startColumn.get(entryKey)!=null){ sb.append(" and ").append(entry.getKey()).append(" > ?"); values.add(startColumn.get(entryKey)); if (this.endColumn.get(entryKey)!=null) { sb.append(" and ").append(entry.getKey()).append(" < ?"); values.add(endColumn.get(entryKey)); } }else if(this.startAndEqualsColumn.contains(entryKey)){ sb.append(" and ").append(entry.getKey()).append(" >= ?"); values.add(entry.getValue()); }else if(this.endColumn.get(entryKey)!=null){ sb.append(" and ").append(entry.getKey()).append(" < ?"); values.add(endColumn.get(entryKey)); if (this.startColumn.get(entryKey)!=null) { sb.append(" and ").append(entry.getKey()).append(" > ?"); values.add(startColumn.get(entryKey)); } }else if(this.endAndEqualsColumn.contains(entryKey)){ sb.append(" and ").append(entry.getKey()).append(" <= ?"); values.add(entry.getValue()); }else{ if (!inColumn.containsKey(entryKey)&&!regexpColumn.containsKey(entryKey)) { sb.append(" and ").append(entry.getKey()).append(" = ? "); values.add(entry.getValue()); } } if (inColumn.containsKey(entryKey)) { StringBuffer buffer = new StringBuffer(); for (Object object : inColumn.get(entryKey)) { if (object instanceof Integer) { buffer.append(((Integer) object).intValue()); }else if (object instanceof Long) { buffer.append(((Long) object).longValue()); }else if (object instanceof String){ buffer.append("'").append(String.valueOf(object)).append("'"); } buffer.append(","); } sb.append(" and ").append(entry.getKey()).append(" in( "); sb.append(buffer.substring(0, buffer.length()-1)); sb.append(")"); } if (regexpColumn.containsKey(entryKey)) { Map<String, String> map = regexpColumn.get(entryKey); for (Entry<String, String> entrys : map.entrySet()) { sb.append(" and ").append(entry.getKey()).append(" REGEXP '(^").append(entrys.getValue()).append(entrys.getKey()).append(")"); sb.append("|(").append(entrys.getKey()).append(entrys.getValue()).append(entrys.getKey()).append(")"); sb.append("|(").append(entrys.getValue()).append(")"); sb.append("|(").append(entrys.getKey()).append(entrys.getValue()).append("$)'"); } } } } sb.append(" ").append(orderBy); }
这个异常很奇怪,又发现Polardb数据库日志中有对应的查询SQL。能看出Model查询操作也是成功的,扫描行数是1,查询状态是成功。
项目:JFinal