Jboss下使用spring配置实现JTA全局事务管理(下)
2017-05-12 09:26
766 查看
前言
上一篇初步简单实现事务管理,只是针对单数据源实现,对单数据源内的操作能够回滚。出现多个数据源,且多个数据源的操作出现在同一个service方法中时,不能实现多个数据源操作同时回滚,本篇将介绍简单实现jta全局事务。JBoss下配置数据源
应用服务器下配置数据源,项目中通过jndi方式引入,这里以jboss为例,配置 standalone.xml ,设置数据源url,username,password,同时设置jndi name。如下:<datasources> <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true"> <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1</connection-url> <driver>h2</driver> <security> <user-name>sa</user-name> <password>sa</password> </security> </datasource> <datasource jndi-name="java:/pocDS" pool-name="mysqlDS_bdpponldb_1" enabled="true" use-java-context="false"> <connection-url>jdbc:mysql://IP1:port1/database1</connection-url> <driver>MYSQL</driver> <security> <security-domain>EncryptedPassword_**_1</security-domain> </security> </datasource> <drivers> <driver name="h2" module="com.h2database.h2"> <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class> </driver> <driver name="MYSQL" module="com.mysql"> <driver-class>com.mysql.jdbc.Driver</driver-class> </driver> </drivers> <datasource jndi-name="java:/jdbc/mgmdb" pool-name="mysqlDS_ccmgmdb_1" enabled="true" use-java-context="false"> <connection-url> jdbc:mysql://IP2:port2/database2</connection-url> <driver>MYSQL</driver> <security> <security-domain>EncryptedPassword_**_1</security-domain> </security> </datasource> <datasource jndi-name="java:/jdbc/onldb " pool-name="mysqlDS_cconldb_2" enabled="true" use-java-context="false"> <connection-url> jdbc:mysql://IP3:port3/database3</connection-url> <driver>MYSQL</driver> <security> <security-domain>EncryptedPassword_**_2</security-domain> </security> </datasource> <datasource jndi-name="java:/jdbc/webdb " pool-name="mysqlDS_ccwebdb_3" enabled="true" use-java-context="false"> <connection-url> jdbc:mysql://IP4:port4/database4</connection-url> <driver>MYSQL</driver> <security> <security-domain>EncryptedPassword_ccwebdb_3</security-domain> </security> </datasource> <datasource jndi-name="java:/jdbc/webdbck" pool-name="mysqlDS_ccwebdb_4" enabled="true" use-java-context="false"> <connection-url>jdbc:mysql://IP5:port5/database5</connection-url> <driver>MYSQL</driver> <security> <security-domain>EncryptedPassword_ccw***b_5</security-domain> </security> </datasource> </datasources>
配置好多个datasource之后,在spring.xml中引入。如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <!-- 管理库 --> <bean id="dataSourceMgm" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:/jdbc/mgmdb</value> </property> </bean> <bean id="sessionFactoryMgm" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSourceMgm" /> <property name="packagesToScan" value="com.packge.*" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider </prop> <prop key="hibernate.connection.characterEncoding">utf-8</prop> <prop key="hibernate.connection.useUnicode">true</prop> <prop key="hibernate.show_sql">true</prop> <prop key="javax.persistence.validation.mode">none</prop> </props> </property> </bean> <bean id="transactionManagerMgm" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactoryMgm" /> </bean> <bean id="hibernateTemplateMgm" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactoryMgm" /> </bean> <bean id="jdbcTemplateMgm" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSourceMgm" /> </bean> <!-- 库2 --> <bean id="dataSourceOnl" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:/jdbc/onldb</value> </property> </bean> <bean id="sessionFactoryOnl" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSourceOnl" /> <property name="packagesToScan" value="com.packge.*" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider </prop> <prop key="hibernate.connection.characterEncoding">utf-8</prop> <prop key="hibernate.connection.useUnicode">true</prop> <prop key="hibernate.show_sql">true</prop> <prop key="javax.persistence.validation.mode">none</prop> </props> </property> </bean> <bean id="transactionManagerOnl" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactoryOnl" /> </bean> <bean id="hibernateTemplateOnl" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactoryOnl" /> </bean> <bean id="jdbcTemplateOnl" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSourceOnl" /> </bean> <!--3库 --> <bean id="dataSourceWeb" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:/jdbc/webdb</value> </property> </bean> <!-- <bean id="dataSourceWeb" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://172.18.63.18:60004/ccwebdb"></property> <property name="user" value="cc_webdb"></property> <property name="password" value="cc_webdb"></property> <property name="maxPoolSize" value="200"></property> <property name="minPoolSize" value="50"></property> </bean> --> <bean id="sessionFactoryWeb" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSourceWeb" /> <property name="packagesToScan" value="com.packge.web.*" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider </prop> <prop key="hibernate.connection.characterEncoding">utf-8</prop> <prop key="hibernate.connection.useUnicode">true</prop> <prop key="hibernate.show_sql">true</prop> <prop key="javax.persistence.validation.mode">none</prop> </props> </property> </bean> <bean id="transactionManagerWeb" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactoryWeb" /> </bean> <bean id="hibernateTemplateWeb" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactoryWeb" /> </bean> <bean id="jdbcTemplateWeb" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSourceWeb" /> </bean> <!-- 4库 --> <bean id="dataSourceWebdbck" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:/jdbc/webdbck</value> </property> </bean> <!-- <bean id="dataSourceWebdbck" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://172.18.63.5:60002/ccwebdb"></property> <property name="user" value="cup_dba"></property> <property name="password" value="OStem@00"></property> <property name="maxPoolSize" value="200"></property> <property name="minPoolSize" value="50"></property> </bean> --> <bean id="sessionFactoryWebdbck" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSourceWebdbck" /> <property name="packagesToScan" value="com.packge.cc.ds.webdbck.*" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider </prop> <prop key="hibernate.connection.characterEncoding">utf-8</prop> <prop key="hibernate.connection.useUnicode">true</prop> <prop key="hibernate.show_sql">true</prop> <prop key="javax.persistence.validation.mode">none</prop> </props> </property> </bean> <bean id="transactionManagerWebdbck" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactoryWebdbck" /> </bean> <bean id="hibernateTemplateWebdbck" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactoryWebdbck" /> </bean> <bean id="jdbcTemplateWebdbck" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSourceWebdbck" /> </bean> </beans>
如果按上述配置之后,配置tx时,需要如下配置,否则会报错,找不到默认的 tansactionManager,
<tx:annotation-driven transaction-manager="transactionManagerMgm"/> <tx:annotation-driven transaction-manager="transactionManagerOnl"/> <tx:annotation-driven transaction-manager="transactionManagerWeb"/> <tx:annotation-driven transaction-manager="transactionManagerWebdbck"/>
这样配置之后,发现并没有jta的影子,因为还没有实现全局事务,上述依旧不能多数据源回滚。 需要在bean配置中,添加如下配置:
<bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
同时,tx配置需要改为:
<tx:annotation-driven transaction-manager="jtaTransactionManager"/>
而不需要配置每个数据源的transactionManager。
JAVA代码中测试:
@Autowired private TblCcmgmUsrInfDao userInfoDao; @Autowired private TblCcmgmMchntDao mchntInfDao; @Autowired private TblCcmgmRoleFunctionRelatedDao roleFunctionRelatedDao; @Autowired private TblCloudzdAcpBillInfoDao billDao; @Autowired private OnlBillInfDao onlBillDao; @Override public void updateUsrPwd(UserInfoDto dto) { TblCcmgmUsrInf usrInf = userInfoDao.get(dto.getUsrIded()); usrInf.setUsrPwd(dto.getUsrPwd()); usrInf.setRecUpdTs(new Timestamp(new Date().getTime())); usrInf.setRecUpdUsrId(dto.getCurrentUsrId()); userInfoDao.modify(usrInf); logger.info("jta test"); TblCloudzdAcpBillInfo inf = new TblCloudzdAcpBillInfo(); inf.setType("q"); billDao.save(inf); TblCconlBillInf billInf = new TblCconlBillInf(); billInf.setBillDate("4688grsegsr654gserrggggggggggggggggggggggggggggggggggggggg"); onlBillDao.save(billInf); }
最后一个因字段长度超限而插入失败,则前面所有数据操作均回滚。
最后
该实现未经过充分测试,还需要到具体项目中,测试性能等是否有坑。这里只介绍简单的Jboss下,mysql+hibernate+jta的简单实现。网上还有许多其他方式实现,如JTOM,atomikos方式实现的,各种方法没有做过比较及充分测试。自己学习过程的整理,如果有不对之处,请大牛指点。相关文章推荐
- Jboss下使用spring配置实现JTA全局事务管理(上)
- Spring学习笔记(18)----使用Spring配置文件实现事务管理
- 使用Spring配置文件实现事务管理
- Spring学习笔记(18)----使用Spring配置文件实现事务管理
- Spring全局事务之JBOSS JTA实现Oracle、Ms SqlServer在同一事务中
- (转)使用Spring配置文件实现事务管理
- 使用Spring配置文件实现事务管理
- Spring学习笔记(16)----使用Spring配置文件实现事务管理
- Weblogic8.1实现(CMT)及spring管理JTA事务
- Spring2.5.x以后使用注解方式的事务管理配置
- 详细配置说明||Spring 使用注解方式进行事务管理
- 使用spring实现事务管理(@transactional)的遇到的两个异常:java.lang.noclassdeffounderror:org/objectweb.asm
- Spring 使用注解方式进行事务管理 /==/ Spring分布式事务实现
- spring事物配置,声明式事务管理和基于@Transactional注解的使用 [转]
- 基于纯Java代码的Spring容器和Web容器零配置的思考和实现(1) - 数据源与事务管理
- spring mvc+hibernate 实现事务管理(配置文件版)
- spring+jta实现全局事物管理
- 使用Spring 2.0 新特性实现声明式事务管理-基于XML Schema
- 使用Spring 2.0 新特性实现声明式事务管理-基于Annotation
- spring事物配置,声明式事务管理和基于@Transactional注解的使用