Essentially, you need some kind of flexible transaction management that automatically detects whether to participate in existing transactions or execute in individual ones, correctly applying commits and rollbacks in any case. Native transactions on JDBC's Connection.commit or Hibernate's Transaction do not handle this, are are arguably not supposed to in the first place.
One solution is to use EJBs, i.e. local Stateless Session Beans. Marking methods as PROPAGATION_REQUIRED will automatically participate in existing transactions but still execute in individual ones else. Of course, it's pretty heavy to make each data access or business object an EJB, but it would work. You would also need to use transactional container DataSources and configure Hibernate's JTATransactionManagerLookup.
The Spring Framework offers a lightweight alternative for such transaction demarcation needs: generic transaction management strategies, with programmatic and declarative means of demarcation. In the Hibernate case, HibernateTransactionManager and JtaTransactionManager are appropriate strategies. Application code does not have to care about the actual strategy as it demarcates transactions in generic ways.
Have a look at the FAQ entry "How to handle transactions that span multiple data access objects?" at
http://www.hibernate.org/74.html. For a more elaborate discussion, see the article at
http://www.hibernate.org/110.html, in particular sections 5 to 7. Of course, I'm also happy to answer further questions if you're interested!
Juergen
(Spring Framework developer)