This project can reproduce the race condition when MyBatis builds mappedStatements:
- Set a breakpoint on line 709 of
HashMap(Oracle JDK 1.8.0_321), and set the breakpoint pause mode toThread, and set the breakpoint condition to:this.getClass().getName().equals("org.apache.ibatis.session.Configuration$StrictMap"). - Start
me.tianshuang.MybatisRaceConditionApplicationin debug mode. - Whenever a breakpoint is reached, hit
Resume Programand watch the console output, becausetabledoes not contain thevolatilemodifier, other threads may not be able to see the latesttablereference in real time, so we may need hitResume Programmultiple times, and when other threads access the latesttablereference and the migration of elements in theoldTabhas not yet completed,org.apache.ibatis.session.Configuration.StrictMap#getwill throwjava.lang.IllegalArgumentException: Mapped Statements collection does not contain value for me.tianshuang.mapper.Mapper1.select1.
Example of breakpoint setting:
Breakpoint detail:
The exception information caused by race condition is as follows:
Number of successful calls before application ready: 1028910
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for me.tianshuang.mapper.Mapper1.select1
### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for me.tianshuang.mapper.Mapper1.select1
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:96)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:441)
at com.sun.proxy.$Proxy48.selectOne(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:160)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:87)
at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:145)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86)
at com.sun.proxy.$Proxy51.select1(Unknown Source)
at me.tianshuang.MybatisRaceConditionApplication.lambda$raceConditionTest$0(MybatisRaceConditionApplication.java:32)
at java.lang.Thread.run(Thread.java:750)
Caused by: org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for me.tianshuang.mapper.Mapper1.select1
### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for me.tianshuang.mapper.Mapper1.select1
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:153)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:145)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:76)
at sun.reflect.GeneratedMethodAccessor34.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427)
... 8 more
Caused by: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for me.tianshuang.mapper.Mapper1.select1
at org.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:1054)
at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:844)
at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:837)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:150)
... 15 more

