Leaving open connections is the point of the pooling but leaving open transactions seems totally broken to me. The connection should be reset when it is returned to the pool: https://docs.sqlalchemy.org/en/20/core/pooling.html#reset-on-return
Maybe turn on pool logging as seen here: https://docs.sqlalchemy.org/en/20/core/pooling.html#logging-reset-on-return-events
Also I saw this but I'm not sure it affects you:
https://docs.sqlalchemy.org/en/20/dialects/mssql.html#mssql-reset-on-return