Even if the session object is the same (which it is) I believe transactional state has been properly cleaned up by zope.sqlalchemy invoking rollback/commit/close on the session itself. However the session and any strong refs it's storing may never be released. As far as I know this shouldn't actually cause a problem but it is a smell for sure.
If you're stuck with the global session (of course I recommend switching), you may just want to add a tween OVER pyramid_tm that invokes DBSession.remove(). This can be done very simply. For example:
def tm_cleanup_tween_factory(registry, handler):
def tween(request):
try:
return handler(request)
finally:
DBSession.remove()
return tween
def includeme(config):
config.add_tween(__name__ + '.tm_cleanup_tween_factory', over='pyramid_tm.tm_tween_factory')
Then in your app just config.include('dotted.path.to.this.module') next to your config.include('pyramid_tm') logic.