项目使用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能查到结果,其它查询都返回nullpublic 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