{"record":{"id":"4553545cfa604964","repo":"mybatis/mybatis-3","slug":"error-cannot-rollback-no-managed-session-is-st","errorCode":null,"errorMessage":"Error:  Cannot rollback.  No managed session is started.","messagePattern":"Error:  Cannot rollback\\.  No managed session is started\\.","errorType":"exception","errorClass":"SqlSessionException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/session/SqlSessionManager.java","lineNumber":302,"sourceCode":"      throw new SqlSessionException(\"Error:  Cannot commit.  No managed session is started.\");\n    }\n    sqlSession.commit();\n  }\n\n  @Override\n  public void commit(boolean force) {\n    final SqlSession sqlSession = localSqlSession.get();\n    if (sqlSession == null) {\n      throw new SqlSessionException(\"Error:  Cannot commit.  No managed session is started.\");\n    }\n    sqlSession.commit(force);\n  }\n\n  @Override\n  public void rollback() {\n    final SqlSession sqlSession = localSqlSession.get();\n    if (sqlSession == null) {\n      throw new SqlSessionException(\"Error:  Cannot rollback.  No managed session is started.\");\n    }\n    sqlSession.rollback();\n  }\n\n  @Override\n  public void rollback(boolean force) {\n    final SqlSession sqlSession = localSqlSession.get();\n    if (sqlSession == null) {\n      throw new SqlSessionException(\"Error:  Cannot rollback.  No managed session is started.\");\n    }\n    sqlSession.rollback(force);\n  }\n\n  @Override\n  public List<BatchResult> flushStatements() {\n    final SqlSession sqlSession = localSqlSession.get();\n    if (sqlSession == null) {\n      throw new SqlSessionException(\"Error:  Cannot rollback.  No managed session is started.\");","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/session/SqlSessionManager.java#L284-L320","documentation":"SqlSessionManager.rollback() throws SqlSessionException 'Cannot rollback. No managed session is started.' when the thread-local managed session is null. Rollback targets the transaction bound to the managed session; with no session started there is nothing to roll back and the manager treats it as a programming error rather than a no-op.","triggerScenarios":"rollback() in a catch block when startManagedSession() itself failed or was skipped; rollback after close(); rollback on a thread that never started the session.","commonSituations":"Exception paths where the session-start line is inside the try and never executed; cleanup code in finally blocks that assumes a session exists; multi-threaded request handling.","solutions":["Start the managed session before the try block so rollback is always valid: startManagedSession(); try { ... commit(); } catch (Exception e) { rollback(); } finally { close(); }.","Guard rollback with isManagedSessionStarted() in defensive cleanup code.","Do not call rollback after close(); close() ends the lifecycle."],"exampleFix":"// before\ntry { sqlSessionManager.update(...); sqlSessionManager.commit(); }\ncatch (Exception e) { sqlSessionManager.rollback(); } // may throw if start failed\n// after\nsqlSessionManager.startManagedSession();\ntry { sqlSessionManager.update(...); sqlSessionManager.commit(); }\ncatch (Exception e) { sqlSessionManager.rollback(); }\nfinally { sqlSessionManager.close(); }","handlingStrategy":"validation","validationCode":"sqlSessionManager.startManagedSession();\ntry { /* work */ sqlSessionManager.commit(); }\ncatch (Exception e) { sqlSessionManager.rollback(); throw e; }\nfinally { sqlSessionManager.close(); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Place startManagedSession() before the try so rollback never runs session-less.","Never call rollback after close().","Guard defensive rollback with isManagedSessionStarted()."],"tags":["mybatis","session-management","transaction","rollback"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}