This is a surprisingly difficult issue and it’s under active research for the best approach.
The short answer is that each snap is an independent process and each account for each snap is also an independent instance. That’s not a problem - as you suggest we can use the account information to create a key into a static cache in order to retrieve a previously established connection.
The not-so-short answer is that we recently switched to using a single classloader for all snaps and accounts in a pipeline but then encountered a situation where one pipeline had snaps with accounts that depend upon mutually incompatible driver jars. I know we were discussing reintroducing separate classloaders for accounts but I don’t know the details. E.g., are the classes marked with an @Account annotation loaded via a different classloader, or only the objects set via Guice injection? Let me know if you need to know the details.
In practice? You should be fine using a static cache (e.g., a Guice Cache object, or a WeaklyLinkedMap) as long as your cache is declared to use the most general thing possible. E.g., return a DataSource instead of an OracleDataSource, much less an Oracle12xArticulatingGumboDataSource.
As an aside - unless you have a compelling reason to do otherwise your cache should contain factories instead of specific instances. JDBC DataSources instead of JDBC Connections, JMS Connections instead of JMS Sessions. It’s not any more difficult to implement and it guarantees each snap gets a fresh, thread-safe copy.