我想使用MyBatis(3.5.1)将批处理插入PostgreSQL。当我在sqlSession上提交时,出现异常org.apache.ibatis.executor.ExecutorException:无法提交,事务已关闭

虽然一张一张地插入记录也可以。

我使用自动提交标志设置为false来创建SqlSession。

mapper.xml

<insert id="saveAll" parameterType="com.test.Event"
            useGeneratedKeys="true" keyProperty="id" keyColumn="id">
        INSERT INTO test.events (device_id, user_name)
        VALUES
        <foreach collection="events" item="event" separator=",">
            (#{event.deviceId}, #{event.username})
        </foreach>
</insert>


储存库类别

public void saveAll(List<Event> events) {
        try (SqlSession sqlSession = transactionManager.getSession()) {
            EventMapper mapper = sqlSession.getMapper(EventMapper.class);
            mapper.saveAll(events);
        }
}



主要

SqlSession sqlSession =  SqlSessionFactoryConfig.getFactory().openSession(false);
try {
     repository.saveAll(events);
     sqlSession.commit();
} catch (Exception ex) {
     LOGGER.info("Exception was occured.", ex);
     handleSqlSessionWhenException(sqlSession);
     throw ex;
} finally {
     handleSqlSession(sqlSession);
}


堆栈跟踪

Exception was occured.
org.apache.ibatis.exceptions.PersistenceException:
### Error committing transaction.  Cause: org.apache.ibatis.executor.ExecutorException: Cannot commit, transaction is already closed
### Cause: org.apache.ibatis.executor.ExecutorException: Cannot commit, transaction is already closed
    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.commit(DefaultSqlSession.java:226)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.commit(DefaultSqlSession.java:217)


有什么办法吗?

谢谢

最佳答案

您的saveAll方法关闭SqlSession并结束事务。

try with resources语句在try块之后调用SqlSession.close`:

try (SqlSession sqlSession = transactionManager.getSession()) {
    EventMapper mapper = sqlSession.getMapper(EventMapper.class);
    mapper.saveAll(events);
}


为了首先解决此问题,您需要确保使用相同的SqlSession。根据transactionManager.getSession的确切含义,它可能会返回与调用SqlSession的代码相同的repository.saveAll

解决此问题并使用相同的会话后,需要删除try块,以便该会话不会自动关闭。

10-05 23:56