Thanks for the response Eduardo.
We actually aren't using
either directly, but are rather using MapperScannerConfigurer to provide the DAOs. And actually, the MapperScannerConfigurer was being wired directly with the SqlSessionFactory. I switched to passing in a SqlSessionTemplate but got the same result; I think some magic along the line was causing the earlier approach to use SqlSessionTemplate anyway.
I've done some debugging of the MyBatis code and I don't see code where the local cache respects nested transactions. When SqlSessionTemplate decides which SqlSession to use, it asks SqlSessionUtils.getSqlSession. This uses a Spring mechanism which associates a resource with a transaction. However, this mechanism only seems to care about the outer transaction in a nested chain, so one SqlSession is used for the outer and inner transactions. And I think that would be OK, but SqlSession does not seem to have its cache invalidated when the inner transaction is rolled back. Nowhere do I see MyBatis take any interest in nested transactions.
Is local caching broken maybe? It does seem to be overly aggressive, e.g. it caches even when using "read uncommitted" isolation.
If I can boil this down to a reproducible example, it'll probably still be quite a bit of code. Is this an appropriate venue for that, or should I post it directly as a MyBatis issue?