最近在部署性能測試環境的時候,環境 部署好以后,部分功能出現接口查詢異常,問題現象:
拿到錯誤,肯定要先判斷是前端還是后端代碼的問題,最簡單的方式是抓包查看:
以上是報錯頁面捕獲的接口報錯,很明顯的接口已經報錯了,那么就直接查看后端的日志:
查看日志分兩步:
1.查看網關web端的日志:
從日志可以知道,出錯的地方在selectOrgDetail接口查詢上
com.xxx.postlend.debtmanagement.service.org.impl.OrgServiceImpl.selectOrgDetail(OrgServiceImpl.java:42)
2.繼續查看APP服務端的日志報錯:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException:
nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2
你想查詢一條數據,但是從數據庫返回兩條數據
看到這個錯誤,就知道是查詢數據庫的記錄,查詢到2條,而期望的結果是1條,即selectOne函數的查詢結果,導致報錯
到這個錯誤的原因就是因為你的查詢方法中得到兩個兩個結果集,然而你的返回用了一個實體去接收,程序這個時候就不知道如何去分配了,很果斷的報這個錯,
修改方法為使用一個list來接收就沒有問題了。
其實從這個selectOne方法也可以猜出來
期望selectOne()返回一個結果(或null),但找到:2
然后我就看了下dao層的接口 是Office getOffice(id); 查的是一條數據,可結果返回的是2條數據的結果集。當然報錯咯!
解決方法是將接口改為list
List<Office>getOffice(String id);
mybatis和spring整合后,dao中的接口
public Student getUser(Student userStudent);
會自動選擇selectOne()方法,由於只能返回一個對象的結果,當返回到多個對象的結果集時報錯。getUser是一個student類的bean無法接受多個結果集,則改用List就可以接受多個結果集
將dao中的
public Student getUser(Student userStudent);
改為
import java.util.List;
public List<Student> getUser(Student userStudent);
從日志報錯的信息查看,問題出現在APP端的代碼如下:
at com.xxx.postlend.debtoauth2.service.biz.impl.OrganizationServiceImpl.selectOrgDetailInfo(OrganizationServiceImpl.java:217)
通過代碼查看,這個selectOne查詢方式是mybatis框架的自動生成sql查詢語句,所以無法查看具體的sql mapper映射文件
需要通過監控,這個接口執行的所有sql如下:
拿到上述的sql去mysql客戶端工具里執行驗證一下,查看是否存在主鍵查詢出現兩條記錄的sql
果然發現存在2個orgId導致的報錯,刪除兩個記錄中的一個
問題完美解決
通過這個例子,其實大家在測試過程中肯定會遇見各種各樣的環境問題,當出現問題的時候,首先判斷問題的類型
然后通過web端還是app端的問題,通過日志打印的堆棧,以及查看代碼的方式,尋找問題的出現的原因,這樣才能慢慢的提升