最近单位有一个网站的数据库负载过重,考虑进行数据库拆分,问题就来了,拆分以后数据库的事务处理咋办?因为以前写的java程序没有考虑到分布式事务。正好前两天接触了JOTM,这是个好东西。废话少说,马上开工。
网上查了好多关于3者的整合,但大都是Spring+Hibernate+JTOM的,很少有直接Hibernate+JOTM的(有,但很少),还是自己动手吧。
一.所需组件
- Hibernate3.2
- JOTM2.0 http://jotm.objectweb.org
- Tomcat5.5
- Carol 2.0.5 http://download.forge.objectweb.org/carol/carol-2.0.5-src.tgz
二.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