來源:http://h5ip.cn/aJgJ
Mybatis是一個開源的輕量級半自動化ORM框架,使得面向?qū)ο髴?yīng)用程序與關(guān)系數(shù)據(jù)庫的映射變得更加容易。MyBatis使用xml描述符或注解將對象與存儲過程或SQL語句相結(jié)合。Mybatis最大優(yōu)點是應(yīng)用程序與Sql進行解耦,sql語句是寫在Xml Mapper文件中。OGNL表達式在Mybatis當(dāng)中應(yīng)用非常廣泛,其表達式的靈活性使得動態(tài)Sql功能的非常強大。OGNL是Object-Graph Navigation Language的縮寫,代表對象圖導(dǎo)航語言。OGNL是一種EL表達式語言,用于設(shè)置和獲取Java對象的屬性,并且可以對列表進行投影選擇以及執(zhí)行l(wèi)ambda表達式。Ognl類提供了許多簡便方法用于執(zhí)行表達式的。Struts2發(fā)布的每個版本都會出現(xiàn)的新的高??蓤?zhí)行漏洞也是因為它使用了靈活的OGNL表達式。公司后端采用Mybatis作為數(shù)據(jù)訪問層,所使用版本為3.2.3。線上環(huán)境業(yè)務(wù)系統(tǒng)在運行過程中出現(xiàn)了一個令人困惑的異常, 該異常時而出現(xiàn)時而不出現(xiàn),構(gòu)造各種OGNL表達式為空等特殊情況均不會重現(xiàn)該異常。具體異常堆棧信息如下:
List的size()方法明顯是public為何還會出現(xiàn)不可訪問的異常。該問題并不是每一次都會出現(xiàn),經(jīng)過多次嘗試,該異常一直未在測試環(huán)境重現(xiàn)。該接口在完整調(diào)用鏈路中的出錯次數(shù)占總調(diào)用次數(shù)的比率為0.01%,無意中聯(lián)想到并發(fā)問題在周期性時間內(nèi)往往是概率性發(fā)生。編寫模擬多線程環(huán)境并發(fā)讀取公司列表測試代碼:
多線程并發(fā)環(huán)境下的壓測代碼
上訴異常堆棧信息在并發(fā)環(huán)境下果然重現(xiàn)出現(xiàn),根據(jù)異常信息代碼執(zhí)行至該行代碼時發(fā)生異常:
異常信息表明OgnlRuntime類不能夠訪問java.util.Collections的私有成員SingletonList。查看源代碼發(fā)現(xiàn)能夠拋出MethodFailedException異??梢枣i定在invokeMethod方法內(nèi)部。
invokeMethod方法代碼
問題出現(xiàn)在method實際上是一個共享變量,也就是例子中的
方法
當(dāng)?shù)谝粋€線程t1至(1)行代碼允許method方法可以被調(diào)用,第二個線程t2執(zhí)行至(2)將method的方法設(shè)置為不可以訪問。接著t1又開始執(zhí)行到(3)行的時候就會發(fā)生該異常。這是一個很典型的同步問題。Ognl2.7已經(jīng)修復(fù)了該問題,因為ognl源碼是直接打包內(nèi)嵌在mybatis包中,mybatis3.3.0版本中也已經(jīng)進行了修復(fù)升級。(劃重點)
【責(zé)任編輯:龐桂玉 TEL:(010)68476606】