MyBatis version
3.5.6
Database vendor and version
mysql 8
Test case or example project
our project do some batch process which has a very long transcation.In the transcation,we use Cursor to traversal the resultSet. The Cursor may be used in a loop.We found that cursor.close() will not release all the resource,so it result in full gc.
the example like below
@Transactional
public List<User> getAllUsersWithReader() throws UnexpectedInputException, ParseException, Exception {
User u = new User();
u.setUserId(1);
userMapper.getById(u);
user2Mapper.getById(u);
List<User> users = new ArrayList<>();
for (int i = 0; i < 100000; i++) {
DcpCursorItemReader<User> reader = new DcpCursorItemReader<>();
reader.setSqlSessionFactory(sqlSessionFactory);
reader.setQueryId("getAllUsersByReader");
reader.open(new ExecutionContext());
User user;
while ((user = reader.read()) != null) {
}
reader.close();
}
return users;
}
Steps to reproduce
use jmeter to test the code ,it result in full gc
we found that in the DefaultSession class, it holds a list of Cursor.When call cursor.close(),the resultSet can be closed ,but the cursor object can not removed from the list hold by DefaultSession.So,when cursor be opened many times,the list will result in full gc
Expected result
cursor.close() should remove cursor object from the list hold by DefaultSession
Actual result
Comment From: xtadg
解决了吗,老哥
Comment From: harawata
This must be a duplicate of #2812 .
You need to specify resultOrderd="true".