I normally just configure all that stuff in the applicationContext.xml and skip the
java code.
There are 2 likely causes.
1. You've got so many concurrent users that the pool is being exhausted. You need to enlarge the pool and possibly the number of connection channels available on both client and database server machines.
2. OR you're not releasing connections fast enough, and that includes possibly leaking them. If you're using Spring Data properly, you shouldn't be leaking connections - that's one of the reasons why I
use Spring Data, in fact. But if your transactions are taking a long time to run, then even without leakage, you can run out. In which case, first consider whether you can optimize the code running while in a transaction and if at all possible move the long-running code outside of the transaction environment. If that doesn't work, see item #1, above.
Some people, when well-known sources tell them that fire will burn them, don't put their hands in the fire.
Some people, being skeptical, will put their hands in the fire, get burned, and learn not to put their hands in the fire.
And some people, believing that they know better than well-known sources, will claim it's a lie, put their hands in the fire, and continue to scream it's a lie even as their hands burn down to charred stumps.