Este artículo estudia principalmente el contenido relevante del mecanismo de transacción de Spring, de la siguiente manera.
Por lo general, hay dos estrategias de transacción: transacciones globales y transacciones locales. Las transacciones globales pueden abarcar múltiples recursos transaccionales (es decir, fuentes de datos, típicamente bases de datos y colas de mensajes), y generalmente requieren la gestión de los servidores de aplicaciones J2EE, lo que requiere el soporte JTA del servidor en la parte inferior. Las transacciones locales están relacionadas con la tecnología de persistencia adoptada por la capa subyacente. Si la capa subyacente usa directamente JDBC, el objeto de conexión debe usarse para operar la transacción. Si se utiliza la tecnología de persistencia hibernada, debe usar el objeto de sesión para operar la transacción.
En general, el proceso de programación que usa transacciones JTA, transacciones JDBC y transacciones hibernadas es más o menos como sigue.
Como se puede ver en la figura anterior, utilizando la programación de transacciones tradicional, el código del programa debe acoplarse con la API de políticas de transacción específicas. Si la aplicación necesita cambiar una estrategia, significa que el código debe modificarse enormemente. Pero si usa transacciones de primavera, no habrá problema.
Srring no proporciona ningún soporte de transacción, solo es responsable de envolver las transacciones subyacentes, y en el nivel de primavera, proporciona una API de programación unificada al mundo exterior. El núcleo de la transacción Spring es la interfaz PlatformTransactionManager.
PlatformTransactionManager representa una interfaz de transacción que es independiente del tipo específico y puede representar cualquier transacción, incluidas las transacciones JDBC, las transacciones hibernadas e incluso las transacciones JTA.
El mecanismo de transacción de Sprera es un modelo de política típico. PlatformTransactionManager representa la interfaz de gestión de transacciones, pero no sabe cómo administrar las transacciones. Solo requiere la gestión de transacciones para proporcionar tres métodos: Iniciar transacción getTransaction(), transacciones commit() y rollback() Sin embargo, la implementación específica se deja a su clase de implementación para completar. Los programadores solo necesitan configurar el tipo de transacción en el archivo de configuración de acuerdo con el tipo de transacción específico utilizado. El resorte subyacente utilizará automáticamente la clase de implementación de transacciones específica para realizar operaciones de transacción. Para los programadores, no necesitan preocuparse por el proceso subyacente, solo necesitan programar la interfaz PlatformTransactionManager. La interfaz PlatformTransactionManager proporciona los siguientes métodos: getTransaction(..), commit(); rollback(); Estas son operaciones de transacción que no están relacionadas con la plataforma.
La escritura completa de getTransaction() es TransactionStatus getTransaction(TransactionDefinition definiton)
Este método se utiliza para devolver un objeto de transacción, y la definición de transacciones de parámetro puede especificar varios atributos para el objeto de transacción. Por lo general, puede especificar los atributos de aislamiento de la transacción, los atributos de propagación, el tiempo de espera y solo leer estos atributos.
La gestión de transacciones específica de Spring requiere que PlatformTransactionManager se configure en el archivo de configuración. La siguiente es la configuración de resorte correspondiente a diferentes tipos de transacciones.
La configuración del administrador de transacciones local de la fuente de datos JDBC es la siguiente:
< p:maxPoolSize="40" p:minPoolSize="2" p:initialPoolSize="2" p:maxIdleTime="30" /> <!-- Configure the local data manager for JDBC data source, use the DataSourceTransactionManager class --> <bean id="transactionManager" p:dataSource-ref="dataSource" />
La configuración del JTA Global Transaction Manager para la gestión de contenedores es la siguiente:
<bean id = "dataSource" p: jndiname = "jdbc /jpetstore" /> <!-Usando la clase jtatransactionManager, esta clase implementa la interfaz PlatformTransactionManager-> <!-Usando las transacciones globales de JTA, los contenedores de Spring pueden obtener recursos transaccionales del servidor JAVA EE en sí mismos sin inyección de dependencia-<<r Bean Id = "TRANSACCIONES CONTENCIONES" /"TRANSACTIONES" /".
Para las transacciones globales de JTA, solo necesita especificar la clase de implementación del administrador de transacciones JtatransactionManager. El contenedor Spring obtendrá la fuente de datos del servidor J2EE por sí mismo, sin inyección explícita en el administrador de transacciones.
La configuración de la transacción local de Spring basada en la tecnología de persistencia de hibernación es la siguiente.
< p: maxpoolSize = "40" P: minpoolSize = "2" P: inicialPoolSize = "2" p: maxidletime = "30" /> <!-Defina la sesión de sessionFactory de Hibernate, SessionFactory necesita RAYA en la fuente de datos, inyect DataSource-> <bean id = "SessionFactory" p: dataSource-ref = "dataScErce <!-annotatedClaSes —Ense —Ense" <!-"! Para enumerar todas las clases persistentes-> <Property Name = "AnnotatedClasses"> <List> <!-Lo siguiente se usa para enumerar todas key = "Hibernate.dialect"> org.hibernate.dialect.mysql5innodbdialect </prop> <!-si para crear tablas de datos basadas en las tablas de asignación de hibernate-> <Pr key = "Hibernate.hbm2ddl.auto"> Actualizar </prop> </prop> </props> </Property> </</</</"! Uso de la clase HibernatetransactionManager-> <!-Esta clase es una implementación específica de la interfaz PlatformTransactionManager para Hibernate-> <!-Configuración de HibernateTransactionManager requiere SessionFactory-> <Bean ID = "TransactionManager" P: SessionFactory-REF = "SessionFactory" />>
Si las transacciones de Spring adoptan la política de Hibernate, generalmente se requieren tres puntos para configurar: fuente de datos, SessionFactory y Transaction Manager.
Si la capa subyacente utiliza tecnología de capa de persistencia hibernada y la transacción utiliza la transacción global JTA, la configuración es la siguiente:
<!-Configurar la fuente de datos JTA-> <bean id = "dataSource" P: jndiname = "jdbc /jpetstore" /> <!-Define Hibernate SessionFactory. SessionFactory debe confiar en la fuente de datos e inyectar datos de datos-> <bean id = "sessionFactory" p: dataSource-ref = "dataSource"> <!-Las clases anotadas se usan para enumerar todas </property> <!-Definir la propiedad de SessionFactory de Hibernate-> <Property name = "HibernateProperties"> <props> <!-Especifique el dialecto de conexión de Hibernate-> <prop key = "hibernate.dialect"> org.hibernate.dialect.mysql5innodbdialect </prop> < Tablas-> <proping key = "hibernate.hbm2ddl.auto"> Update </prop> </props> </property> </bean> <!-Use la clase JTatransactionManager, que es una clase de implementación de la interfaz PlatformTransactionManager-> <!
En comparación con la transacción de primavera basada en Hibernate anterior, esto es para reemplazar la fuente de datos con una fuente de datos JNDI y reemplazar el administrador de transacciones con un JtatransactionManager.
Para las transacciones globales de JTA, debido a que se requiere el soporte del servidor de aplicaciones subyacente, puede haber diferencias en los detalles entre las transacciones globales de JTA proporcionadas por diferentes servidores de aplicaciones. Por lo tanto, al configurar realmente el Global Transaction Manager, es posible que deba utilizar subclases de JtatransactionManager, como OC4JJTATRANSACTIONSManager proporcionado por el servidor de aplicaciones Javaee de Oracle, WebLogicJtatransActionManager proporcionado por Oracle para WebLogic, WebSpherUowTransactionManager proporcionado por IBM para Websphere, etc.
A partir de la configuración de resorte de varios tipos de transacciones anteriores, se puede ver que cuando una aplicación adopta la gestión de transacciones de Spring, la aplicación no necesita estar acoplada con la API de transacción específica. La aplicación solo debe programarse a la interfaz PlatormTransactionManager. El ApplicationContext seleccionará la clase de implementación de política de transacción apropiada (es decir, la clase de implementación de PlatormTransActionManager) en función del archivo de configuración.
Entonces, en detalle cómo realizar la programación de control de transacciones en Spring, generalmente hay dos maneras.
Gestión de transacciones de programación: es utilizar directamente los tres métodos abstractos proporcionados por PlatormTransactionManager para controlar el flujo de transacción en el código. También puede obtener un frijol de platormtransactionManager en el contenedor de primavera. Este bean siempre es una instancia de la clase de implementación específica de PlatormtransactionManager. La clase de implementación específica es seleccionada por AplicationContext de acuerdo con el patrón de política. Los programadores no necesitan preocuparse por ello, solo necesitan programar la interfaz.
Gestión de transacciones declarativas: este método no requiere que el proceso de control de transacciones se escriba en el código, pero usa AOP para completar la incorporación de transacciones completamente a través de archivos de configuración. Es decir, los archivos de configuración XML pueden configurar agentes de transacciones para componentes comerciales, y los agentes de transacciones proporcionan control de transacciones para los componentes comerciales. Ahora este método es el mejor, con la intrusión del código fuente más bajo.
Al usar transacciones declarativas, solo necesita escribir un archivo de configuración y configurar los tipos de componentes que requieren control de transacciones. Los componentes comerciales se tejerán en el control de la transacción bajo el mecanismo AOP, y los programadores no necesitan escribir ningún código de gestión de transacciones y pueden centrarse en el desarrollo de los componentes comerciales. Por lo tanto, generalmente se recomienda la gestión de transacciones declarativas.
El método de esquema XML de Spring proporciona una estrategia de configuración de transacciones concisa. Configura un procesamiento de mejora de la transacción a través del espacio de nombres <tx:advice> , donde se pueden especificar varios atributos de la transacción (como los atributos de aislamiento, los atributos de propagación, el tiempo de espera, los atributos de lectura de lectura, etc.), y luego la mejora de la transacción puede estar vinculada al punto de entrada de la AOP (i.e., el método de ejecución de la frijoles) a través del <aop> configuración: la mejora de la transacción, el punto de entrada de la AOP (i.e., el método de ejecución de la frijoles) a través del <aop: Configuración> Configuración de la transacción. operaciones. Aquí hay un ejemplo simple, configurar un frijol newsDaoMpl para operaciones de datos, usar la fuente de datos C3P0, el administrador de transacciones JDBC de Spring y configurar propiedades para transacciones en <tx: consejo.
La configuración de resorte completa es la siguiente:
<? xml versión = "1.0" encoding = "utf-8"?> <beans xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns = "http://www.springframework.org/schema/Beanss" " xmlns: p = "http://www.springframework.org/schema/p" xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http://www.springframework.org/schema/tx" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/tx/spring-tx-4.0.xsd "! Bean, use la fuente de datos C3P0 para implementarla, e inyecte la información necesaria de la fuente de datos-> <bean id = "dataSource" destruye-method = "cierre" p: conductorclass = "com.mysql.jdbc.driver" p: jdbcurl = "jdbc: mysql: // localhost/test/useunicode = true & caracterescoding" "p.sql" p. = "p.s." p. p: contraseña = "" p: maxpoolSize = "40" P: minpoolSize = "2" P: inicialPoolSize = "2" P: maxidletime = "30" /> <!-Configurar el administrador de datos local de JDBC Fuente de datos, use la clasificación de DataScanActiveManager-> <bean id = "TransActionManager" P: datasource-pref = "datasage" /! Business Logic Bean-> <bean id = "NewsDao" P: DS-REF = "DataSource" /> <!-Configurar procesamiento de mejora de transacciones, especificar el administrador de transacciones-> <tx: consejo id = "txadvice" transacciones-ganager = "TransactionManager"> <!-Utilizado para configurar definiciones detalladas de transacciones-> <TX: Atributes> <tx: método name = "get*" read-Only = "true" /> <!-Todos los demás métodos están sujetos a transacciones de forma predeterminada, especificando un tiempo de espera de 5 segundos-> <tx: name de método = "*" aislamiento = "predeterminado" propagation = "timeout =" 5 " /> < /tx: atributas> < /tx: consejo> <aop: configuración> <!-Configurar un punto de entrada a la entrada de los métodos de la entrada a los métodos. Impl-Ed clases en el paquete Impl-> <aop: PointCut Expression = "Execution (*com.dao.imp.*Impl.*(..))" id = "myPointCut" /> <!-Binding the Entry Point myPointCut y mejore txadvice-> <aop: asesor-recess-ref = "txadvice" punto "punto-ref =" myPointcut " /" /!-Asesor Asesor-ref = "txadvice" Pointcut-ref = "myPointcut" /" /!-Asesor Asesor-Ref =" Txadvice "PointCut-ref =" myPointCut " /" ADSUENTUROR-Reh. La ejecución de todos los métodos en la clase que comienzan con ABC en el paquete Impl -> </aop: config> </beans>
En el código NewsDaOMPL, es insertar datos duplicados en la tabla.
paquete com.dao.impl; import javax.sql.dataSource; import org.springframework.jdbc.core.jdbctemplate; import com.dao.newsdao; public class NewsDaoMpl implementa NewsDao {private DataSource DS; Public Boid setds (datasource ds) Void Insert (Title String, contenido de cadena) {// Uso de C3P0 Data Pool jdbctemplate jt = new JDBCTemplate (ds); jt.update ("insertar en news_inf" + "valores (100,?,", Title, Content); jt.update ("Insertar en News_inf" + "Valores (100,?,?,?,", Title, Content); Control, se puede insertar el primer registro // Si se agrega el control de la transacción, el primer registro no se insertará}}Aquí está el método de prueba.
public static void test3 () {ApplicationContext CTX = new ClassPathXMLApPlicationContext ("Beans4jdbc.xml"); // Obtenga el agente de transacciones Bean NewsDao Dao = (NewsDao) CTX.GetBean ("NewsDao", NewsDao.Class); Dao.insert ("Idea central de la programación de Java", "Desarrollo de Java EE liviano"); System.out.println ("Ejecución completada"); }La ejecución del método de prueba encontrará que se lanza una excepción (debido a datos duplicados) y debido al control de transacciones, no habrá inserción de datos en la base de datos.
Como puede ver en el ejemplo anterior, generalmente en la configuración del esquema XML, una configuración de AOP realmente se realiza para un frijol ordinario y se incorpora una mejora de consejos. La mejora de los consejos se configura con un administrador de transacciones, que se basa en la fuente de datos.
Para <aop: Advisor>, la vinculación de consejos y puntos de entrada es realizado por el postprocesador de Bean en la parte inferior de la primavera (como BeannameautOproxyCreator, defaultadVisoraUtoproxyCreator), que es esencialmente un proxy dinámico.
Además, en la mejora de la configuración <tx: consejo>, también puede especificar que cuando se encuentra una excepción específica, fuerza la reversión y la fuerza no reversa, es decir, Rollback-For = "XXXException", no-Rollback-For = "xxxexception"
Además de usar métodos de esquema XML, también puede agregar directamente la anotación de @Transaction al método para que este método tenga propiedades transaccionales. En @Transaction, se pueden configurar varias propiedades para transacciones (como propiedades de aislamiento, propiedades de propagación, tiempos de espera, propiedades de solo lectura, etc.). Además, es necesario agregar una configuración A <TX: Control de anotación a la configuración XML, lo que indica que Spring configurará el agente de transacciones de acuerdo con la anotación, de modo que la configuración de la propiedad de la transacción y la configuración de corte AOP se pueden completar en un solo paso (directamente a través de la configuración de anotación en el nombre del método).
<tx: transacción-manager de anotación = "TransactionManager" />
NewsDaoImpl.
@Transactional (propagation = propagation.required, isolation = isolation.default, timeout = 5) @OverridePublic void inser (título de cadena, contenido de cadena) {Lo anterior es todo el contenido de este artículo sobre el código de ejemplo del mecanismo de transacción de Spring, y espero que sea útil para todos. Los amigos interesados pueden continuar referiéndose a otros temas relacionados en este sitio. Si hay alguna deficiencia, deje un mensaje para señalarlo. ¡Gracias amigos por su apoyo para este sitio!