Approach # 1
For us, scalability is important and we use your approach #1.
We deploy isolated instances of Hibernate (as a service behind Tomcat servers in EC2). When demand increases and more instances are needed, it's easy to add more instances.
Benefits of this approach:
- encapsulation (not in the OO sense), as each instance is configured
in isolation
- easier configuration, as only a single instance image is
needed.
- scalable
About transaction management: this is done by the DB engine itself; not by Hibernate, and not by EC2 as you mentioned. You can have one large instance of MySQL as an RDS and it can handle transactions from several "clients" (Hibernate, JDBC, SQL Concoles, etc.).
Hibernate in this case 'doesn't matter'. The DB will also gracefully handle concurrency and deadlocks (may need tweaking) if this is what you're worried about. I think if you look at this architecture from a database engine perspective, things become easier to understand. You don't need a centralized integration tier (like Hibernate) to make sure the DB handles all transactions. The database is responsible for that.
Approach #2
I never seen it nor used it. Although theoretically it could provide come caching, it isn't scalable. What if you need 100 instances for your app? Will this ONE instance handle all the DB traffic? Probably not, but with approach # 1 it scales nicely. If your concern is only transaction management, approach # 2 isn't necessary.
Final Comments
Things are a bit more complicated when you have multiple MySQL databases instances around the world, instead of a centralized one. In that case, one DB instance doesn't know about the other. Example: your database in the US doesn't know the data of the one in Japan. In this case, nightly batch jobs could help, but consolidation and integration (ETL,EAI) are another issue. Since you have one instance things are more simple (correctly so) and I can't see why approach # 1 wouldn't take care of all the concerns you mentioned.