If a background thread holds a database connection for more than five minutes, the ConnectionPoolHealthSqlInterceptor gets confused with a "-2" low-water mark and it dumps seemingly-incorrect warnings in the logs.
For example, when testing a background thread that was using a connection for five minutes, the ConnectionPoolHealthSqlInterceptor logged the following in relation to an Atlassian-internal OFBIZ call. The stack trace shows that it corresponds to a connection closed within GenericDAO#select (triggered by a IssueManager#getIssueObject):
Note the low water mark of "-2".
The ConnectionPoolHealthSqlInterceptor creates a CountHolder inner class which causes the ThreadLocal to self-destruct after five minutes. Subsequent to that self-destruction, the next connection to be returned to the pool (which is probably the connection for which the taken() method was just previously called) calls the replaced() method, which does not check to see if the low water mark is below zero, and which causes this warning to be logged.
I suppose that the answer could easily be "we don't want your thread to hold database connections for more than 5 minutes", but that notwithstanding, it looks like ConnectionPoolHealthSqlInterceptor is not working quite as intended in this scenario.
Please configure package level logging for com.atlassian.jira.ofbiz to ERROR.
See the attached screenshot for the details.