- 現象
4.0.0-RC1版本,我設定了資料自動生成分布式主鍵ID,然後當我進行資料插入的時候,我發現其中一個字段value值是null的時候,這個自動生成的主鍵ID指派錯亂了。
- 找問題
那咋辦呢?隻能從他的原理以及源碼入手了。設定了自動生成分布式主鍵,那麼他是怎麼操作的呢?
經過一番查詢和測試之後,ShardingSphere是這麼做的。他拿到業務層處理的sql之後,他在這個sql上面進行了改造。舉個例子,我要在user表裡面插入一條資料,sql如下:
INSERT INTO user (name, remark, age) VALUES ('test', null, 18);
然後ShardingSphere會進行處理,他會在我原有的sql上加ID,然後正常得到的sql應該是:
INSERT INTO user (name, remark, age, id) VALUES ('test', null, 18, '主鍵id');
但是事實卻是這樣的:
INSERT INTO user (name, remark, age, id) VALUES ('test', 18, '主鍵id', null);
怎麼會這樣呢?看起來感覺像是最後指派的時候null的情況判斷是有問題的,那麼我們接下去繼續去看源碼。
又是一番debug + 查找之後。。。。
發現有這樣一個抽象類InsertOptimizeResultUnit,其中有一個方法是getCurrentIndex,如下圖:

截屏的這一步操作是在做什麼呢?他主要是查找value這個數組的最後一位的下标是多少,由于他每一次都對value進行了非空判斷,也就是說隻要有一個value值為空,那麼這個下标計算出來就會少1。那麼最後最後造成的結果就是明明他應該在age後面加上id,但是由于下标計算錯誤導緻id的value值去覆寫了age的value值。
解決方案
首先先去github上送出了issue,位址是https://github.com/apache/incubator-shardingsphere/issues/2897
先看ShardingSphere的開發者是否已經解決了這個問題,如果他們要在後續的版本進行解決的話,目前隻有兩個方案解決了:
1.我隻能先暫時對字段加一個預設值,盡量使value不為空(不太好)
2.将github上的代碼拉下來,然後自己修改源碼然後自己打一個包來用(較合适)
若有問題,歡迎一起讨論,一起學習進步!
轉載于:https://my.oschina.net/u/3095034/blog/3095016