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".