1. 程式人生 > >mybatis 資料插入返回主鍵與多執行緒執行產生的錯誤

mybatis 資料插入返回主鍵與多執行緒執行產生的錯誤

今天在碼程式碼時,發現一個錯誤,有時正常有時不正常,完全沒有一個程式該有的節操。在一翻調教下正常了。現留下解決方法備用。

以下原理純屬個人臆測,完全沒有依據,誤導完全不負責任~ 另請明白的大神評論裡解釋,脆謝~

目標描述:

我需要一次並行執行多個執行緒,使用CyclicBarrier 執行緒阻塞,等待全部執行完畢。每一個執行的執行緒呼叫外部介面並收到介面響應,且都有單獨的日誌資訊的DB插入。日誌資訊記錄介面執行前時間和外部介面返回結果時間。

原始碼邏輯:

CyclicBarrier 實現跳過,在每一個執行緒中,我先插入DB一條日誌,通過mybatis 插入返回日誌物件。然後呼叫介面,介面返回後去DB 修改此日誌物件,新增結果與結果返回時間。

錯誤現象:

一般第一次執行時,可以同時執行多執行緒並返回正常結果,但再點就有時候只調用了一次介面,有的時候一次外部介面呼叫都沒有。點多少次都一樣,時好使時不好使。

臆測原因:

mybatis 的插入返回是基於java 反射機制。幾乎同時執行的執行緒程式是一樣的,對於相同物件名造成反射瞎掉。還有一個可能的因素就是DB執行的影響,但我覺得不應該。再次宣告:原理純屬個人臆測,完全沒有依據,誤導完全不負責任~

解決:

1 去掉mybatis 表對映檔案 表名.xml 中 插入的 插入返回。

 <insert id="insert" parameterType="com.xxx.xxx.pojo.xxx" keyProperty="xxId" useGeneratedKeys="true">
...
...
...
</insert>

對 ,說 白了 就是 刪除 keyProperty="xxId" useGeneratedKeys="true" 

2 執行緒開始後先弄個日誌物件記錄下執行時間,但並不插入DB。

3 呼叫介面後在日誌物件裡記錄下返回時間,插入DB

總結:其實就一句話,不要覺得mybatis操作DB方便就隨便用,能少連線DB就少連線!