Couple of options can cause this
1) If your application have long running SQL's that is making the connections to be held for more time , while the SQL's are running for long time there are clients asking for more connections which are not available.
2) You application is causing the connection leak. Close the connection in the finally block rather than in the try , that is correct usage .
Thanks a lot! I follow your suggestion to put session.close() into finally block. It worked.