Cómo crear varios administradores de transacciones y cómo se asocian con los recursos correspondientes que deben sincronizarse con las transacciones (por ejemplo, DataSourceTransactionManager con DataSource de JDBC, HibernateTransactionManager con SessionFactory de Hibernate y así sucesivamente) debería quedar claro ahora. Esta sección describe cómo el código de la aplicación (ya sea directa o indirectamente a través de una API de persistencia como JDBC, Hibernate o JPA) garantiza que estos recursos se creen, reutilicen y limpien adecuadamente. La sección también analiza cómo se puede activar la sincronización de transacciones (opcional) a través del TransactionManager apropiado.

Enfoque de sincronización de alto nivel

El enfoque preferido es utilizar API de integración de persistencia basadas en plantillas de alto nivel de Spring o utilizar API ORM nativas con factory beans orientados a transacciones o proxies para administrar fábricas de recursos nativos. Estas soluciones orientadas a transacciones manejan internamente la creación y reutilización de recursos, la limpieza, la sincronización opcional de recursos con transacciones y la conversión de excepciones. De esta manera, el código de acceso a datos personalizado no necesita manejar estas tareas, sino que puede reorientarse únicamente en una lógica de persistencia de datos no estereotipada. Normalmente, utiliza la API ORM integrada o utiliza un enfoque basado en plantillas para lograr el acceso JDBC utilizando JdbcTemplate. Estas soluciones de software se describen en detalle en las secciones siguientes de esta documentación de referencia.

Enfoque de sincronización de bajo nivel

Clases como DataSourceUtils (para JDBC), EntityManagerFactoryUtils (para JPA), SessionFactoryUtils (para Hibernate), etc., existen en un nivel inferior. nivel. Si necesita que el código de su aplicación funcione directamente con los tipos de recursos de las API de persistencia nativas, utilice estas clases para garantizar que se recuperen las instancias adecuadas administradas por Spring Framework, que las transacciones se sincronicen (opcional) y que las excepciones generadas en el proceso se muestren correctamente. en una interfaz API consistente.

Por ejemplo, en el caso de JDBC, en lugar del enfoque tradicional de JDBC de llamar al método getConnection() en el DataSource, puede utilizar el org.springframework.jdbc clase.datasource.DataSourceUtils de Spring como se muestra a continuación:

Conexión de conexión = DataSourceUtils.getConnection(dataSource);

Si una transacción existente ya tiene una conexión sincronizada (vinculada), se devuelve esta instancia. De lo contrario, llamar al método da como resultado la creación de una nueva conexión, que (opcionalmente) se sincroniza con cualquier transacción existente y está disponible para su reutilización posterior en la misma transacción. Como se mencionó anteriormente, cualquier excepción SQLException está envuelta en una excepción CannotGetJdbcConnectionException de Spring Framewor, que es una de las excepciones en la jerarquía DataAccessException de no verificados. Tipos en Spring Framework. Este enfoque proporciona más información que se puede obtener fácilmente de SQLException y proporciona portabilidad entre bases de datos e incluso entre diferentes tecnologías de almacenamiento persistente.

Este enfoque también funciona sin la administración de transacciones de Spring (la sincronización de transacciones es opcional), por lo que puede usarlo ya sea que use Spring para la administración de transacciones o no.

Naturalmente, después de usar el soporte JDBC, JPA o Hibernate de Spring, generalmente es preferible no usar DataSourceUtils u otras clases auxiliares, ya que será mucho más feliz trabajando a través de la abstracción de Spring que trabajando directamente. Con las interfaces API asociadas. Por ejemplo, si usa el paquete JdbcTemplate de Spring o el paquete jdbc.object para hacer que JDBC sea más fácil de usar, el descubrimiento correcto de la conexión ocurre detrás de escena sin que tenga que escribir ningún código especial. .

TransactionAwareDataSourceProxy

En el nivel más bajo está la clase TransactionAwareDataSourceProxy. Este es un proxy para el DataSource de destino que envuelve el DataSource de destino para mejorar el nivel de compatibilidad de las transacciones administradas por Spring. En este sentido, es similar al DataSource transaccional JNDI proporcionado por el servidor Java EE.

Casi nunca necesitarás o querrás usar esta clase, excepto cuando necesites llamar a código existente y pasarle una implementación estándar de la interfaz DataSource de JDBC. En este caso, es posible que se pueda usar este código, pero está involucrado en transacciones administradas por Spring. Puedes escribir nuevo código personalizado utilizando las abstracciones de nivel superior mencionadas anteriormente.