最近单位有一个网站的数据库负载过重,考虑进行数据库拆分,问题就来了,拆分以后数据库的事务处理咋办?因为以前写的java程序没有考虑到分布式事务。正好前两天接触了JOTM,这是个好东西。废话少说,马上开工。
网上查了好多关于3者的整合,但大都是Spring+Hibernate+JTOM的,很少有直接Hibernate+JOTM的(有,但很少),还是自己动手吧。
一.所需组件
二.JOTM2.0安装
1. 解压 jotm-2.0.10.tgz\jotm-2.0.10\lib 下所有 jar 包到 $TOMCAT5_HOME\common\lib 下
2. 重新编译 carol ,覆盖 $TOMCAT_HOME\common\lib 下的 ow_carol.jar 文件(和 jdk 有关系,所以要自己重新编译一下)
3. 在 $TOMCAT_HOME\common\classes\ 下建立 carol.properties 文件,内容如下(我测试的时候此文件不建立也可以)
# lmi stands for Local Method Invocation (it's a "fake" RMI)
carol.protocols=lmi
# do not use CAROL JNDI wrapper
carol.start.jndi=false
# do not start a name server
carol.start.ns=false
4 . JOTM 安装完成。
三.在Tomcat下建立两个数据源和一个事务处理
<Resource name="zhang/jta1" auth="Container" description="DB Connection jat1" factory="org.objectweb.jndi.DataSourceFactory" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/jta1?autoReconnect=true" username="root" password="" /> <Resource name="zhang/jta2" auth="Container" description="DB Connection jat2" factory="org.objectweb.jndi.DataSourceFactory" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/jta2?autoReconnect=true" username="root" password="" /> <Resource name="UserTransaction" auth="Container" type="javax.transaction.UserTransaction" factory = "org.objectweb.jotm.UserTransactionFactory" jotm.timeout = "60"/>
网上的事务部分一般采用<Transaction>…..</Transaction>配置,但是我测了一下,就是不成,也不知是哪里出了问题,所以改用数据源的形式,效果一样.
注意:
上面配置数据源的时候参数名字一定要写对,开始的时候我的配置文件里面是 c3p0 的配置,当时没注意,就直接把 factory 后面类名改了一下,别的参数都没动,结果调了一天半也没弄好,后来,将 driverClass 改成 driverClassName , jdbcUrl 改成 url , user 改成 username 搞定,郁闷坏了 ……
四.配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <resource-ref> <description>jta1</description> <res-ref-name>zhang/jta1</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> <resource-ref> <description>jt2</description> <res-ref-name>zhang/jta2</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> <resource-ref> <description>UserTransaction description</description> <res-ref-name>UserTransaction</res-ref-name> <res-type>javax.transaction.UserTransaction</res-type> <res-auth>Container</res-auth> </resource-ref> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
五.数据源配好了,下面改Hibernate了
因为是多数据库操作,需要建立两个HibernateSessionFactory和两个Hibernate配置文件。工厂部分代码直接拷贝一份,修改一下其中的CONFIG_FILE_LOCATION就可以了
hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <!-- Generated by MyEclipse Hibernate Tools. --> <hibernate-configuration> <session-factory> <property name="transaction.factory_class"> org.hibernate.transaction.JTATransactionFactory </property> <property name="connection.datasource">java:comp/env/zhang/jta1</property> <property name="jta.UserTransaction">java:comp/env/UserTransaction</property> <property name="transaction.manager_lookup_class">org.hibernate.transaction.JOTMTransactionManagerLookup</property> <property name="show_sql"> true </property> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <mapping resource="com/zhang/pojos/Users.hbm.xml"/> </session-factory> </hibernate-configuration>
hibernate2.cfg.xml
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <!-- Generated by MyEclipse Hibernate Tools. --> <hibernate-configuration> <session-factory> <property name="transaction.factory_class"> org.hibernate.transaction.JTATransactionFactory </property> <property name="connection.datasource">java:comp/env/zhang/jta2</property> <property name="jta.UserTransaction">java:comp/env/UserTransaction</property> <property name="show_sql"> true </property> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <mapping resource="com/zhang/pojos/Address.hbm.xml"/> </session-factory> </hibernate-configuration>
六.测试代码
package com.zhang.test; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.transaction.SystemException; import javax.transaction.UserTransaction; import org.hibernate.Session; import com.zhang.factory.HibernateSessionFactory; import com.zhang.factory.HibernateSessionFactory2; import com.zhang.pojos.Address; import com.zhang.pojos.Users; public class Test { public void insertinto() { UserTransaction tx = null; try { tx = (UserTransaction) new InitialContext().lookup("java:comp/env/UserTransaction"); } catch (NamingException e1) { e1.printStackTrace(); } try { tx.begin(); Session session = HibernateSessionFactory.getSession(); // Users user = new Users(); user.setUsername("SSSSS"); user.setPassword("123"); session.save(user); Session session2 = HibernateSessionFactory2.getSession(); Address address = new Address(); address.setUsersId(1); address.setAddress("XXXXXXX"); session2.save(address); tx.commit(); } catch (Exception e) { e.printStackTrace(); try { tx.rollback(); } catch (IllegalStateException e1) { e1.printStackTrace(); } catch (SecurityException e1) { e1.printStackTrace(); } catch (SystemException e1) { e1.printStackTrace(); } } } }
以上配置本家调试通过,如果有什么问题希望大家留言~共同进步~~
CSDN本人原创.今搬家至ITEYE.版权所有@Robot_G