设为首页 收藏本站
查看: 552|回复: 0

[经验分享] JOTM 分布式事务初探(JNDI,Tomcat 7 JDBC Pool连接池)

[复制链接]

尚未签到

发表于 2017-2-7 11:24:53 | 显示全部楼层 |阅读模式
  JOTM 分布式事务初探(JNDI,Tomcat 7 JDBC Pool连接池)
  Tomcat 7 带了一个新的连接池 tomcat(The Tomcat JDBC Connection Pool)
  网上有人测试,据说性能超过常用连接池(c3p0等).
  链接:http://www.open-open.com/lib/view/open1329182303124.html
  并且这个连接池提供的连接不是普通的Connection,而是pooledConnection,
  而且支持提供XADataSource(org.apache.tomcat.jdbc.pool.XADataSource).
  The Tomcat JDBC Connection Pool可独立使用,
  需要Tomat7版本下lib包中的tomcat-jdbc.jar和bin中的tomcat-juli.jar
  可以用来做JOTM的分布式事务的数据源.
  实际使用tomcat版本 是5.5.25
  JOTM版本 2.1.9 http://jotm.ow2.org/xwiki/bin/view/Main/Download_Releases
  1. 新建一个Java web工程
  将JOTM的lib包下的所有jar包(包括一个空的ext文件夹)拷贝到web-inf的lib下
  将Tomcat版本中的tomcat-jdbc.jar和tomcat-juli.jar拷贝到
  tomcat5.5.25的common\lib下,并引入到工程中来.
  将 mysql和oracle的jdbc驱动拷贝到web-inf的lib下
  (classes12.jar--oracle驱动,mysql-connector-java-5.1.24-bin.jar--mysql驱动)
  需要将web-inf的lib下所有jar包拷贝到tomcat5.5.25的common\lib下,部署的时候,注意将
  webapps\工程\web-inf的lib下的jar全部删除,使用tomcat5.5.25的common\lib下的jar包
  2. 分别在mysql和oracle中创建测试数据库和测试用户
  2.1 mysql数据库(mysql 版本mysql  Ver 14.14 Distrib 5.5.11, for Win32 (x86))
  下面的语句执行前,可能需要使用root用户登陆

GRANT ALL PRIVILEGES ON *.* TO mojo@localhost IDENTIFIED BY 'jojo' WITH GRANT OPTION; -- 创建用户,并授权
create database javatest;
use javatest;
create table testdata (id int not null auto_increment primary key,foo int) engine = innodb;
create unique index index_idfoo on testdata(id,foo); --创建唯一索引
  2.2 oracle数据

create user mojo identified by jojo;
grant dba to mojo;--授予DBA权限  
connect mojo/jojo@serviceid; -- 使用刚刚创建的用户登陆 serviceid 需要修改成实际的
create table testdata (id number(10),foo number(10)); --创建一个表
create unique index index_idfoo on testdata(id,foo);
commit;
  3. 配置carol.properties,放置到src目录下面
  # # JNDI (Protocol Invocation)
  carol.protocols=jrmp
  # Local RMI Invocation
  carol.jvm.rmi.local.call=true
  # do not use CAROL JNDI wrapper
  carol.start.jndi=false
  # do not start a name server
  carol.start.ns=false
  # Naming Factory
  carol.jndi.java.nameing.factory.url.pkgs=org.apache.nameing
  4. 配置tomcat/conf/context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/mysqlDB"
auth="Container"
type="javax.sql.DataSource"
factory="org.objectweb.jotm.datasource.DataSourceFactory"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
validationQuery="SELECT 1"
validationInterval="30000"
timeBetweenEvictionRunsMillis="30000"
maxActive="100"
minIdle="10"
maxWait="10000"
initialSize="10"
removeAbandonedTimeout="60"
removeAbandoned="true"
logAbandoned="true"
minEvictableIdleTimeMillis="30000"
jmxEnabled="true"
jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
username="mojo"
password="jojo"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/javatest"/>
<Resource name="jdbc/oracleDB"
auth="Container"
type="javax.sql.DataSource"
factory="org.objectweb.jotm.datasource.DataSourceFactory"
testWhileIdle="true"
testOnBorrow="true"
testOnReturn="false"
validationQuery="SELECT 1"
validationInterval="30000"
timeBetweenEvictionRunsMillis="30000"
maxActive="100"
minIdle="10"
maxWait="10000"
initialSize="10"
removeAbandonedTimeout="60"
removeAbandoned="true"
logAbandoned="true"
minEvictableIdleTimeMillis="30000"
jmxEnabled="true"
jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
username="mojo"
password="jojo"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@10.47.170.175:1521:zxin"/>
<!-- Resource configuration for UserTransaction
use JOTM
-->
<Transaction factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60"/>

<WatchedResource>WEB-INF/web.xml</WatchedResource>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
</Context>
  上面配置文件中 [size=1em]factory="org.objectweb.jotm.datasource.DataSourceFactory"
  表示使用的是JOMT自己的连接池.
  而配置成 factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
  表示使用 Tomcat 7 JDBC 连接池
  注意上面配置数据库连接时,
  type="javax.sql.DataSource"
  factory="org.objectweb.jotm.datasource.DataSourceFactory"
  两个属性,type总是DataSource,尽管JOTM要求提供XADataSource,
  主要是factory="org.objectweb.jotm.datasource.DataSourceFactory"这个可以根据需要
  选择提供普通的DataSource或者XADataSource.
  这样,假如之前有相关的配置,则修改为支持JOTM分布式事务时,貌似只要修改这个
  factory配置即可.
  <Transaction>是Tomcat 5中的新标记,对于不支持此标记的老版本,
  需要使用以下语句代替事务资源的声明:

<!-- Resource configuration for UserTransaction
use JOTM
-->
<Resource name="UserTransaction" auth="Container"
type="javax.transaction.UserTransaction"
factory = "org.objectweb.jotm.UserTransactionFactory"
jotm.timeout = "60"/>
  需要注意的是,使用<Resource>节点声明的资源默认上下文前缀是"java:comp/env",
  而使用< Transaction>节点时则是"java:comp"。因此,当使用4.2的方式声明用户事务时,
  相应的JNDI查找代码也应该改为 
  UserTransaction ut = (UserTransaction)initCtx.lookup("java:comp/env/UserTransaction");
  上面的配置还配置了一个 UserTransaction.
  5. 在Java类中获取上面配置的资源

Context ctx = new InitialContext();
// JDBC stuff
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/mysqlDB"); //mysql数据源
DataSource dsOra = (DataSource) ctx.lookup("java:comp/env/jdbc/oracleDB");//oarcle数据源
UserTransaction ut = (UserTransaction) ctx.lookup("java:comp/UserTransaction"); //用户事务(分布式)
  6. 测试分布式事务.
  上面在mysql和oracle中分别创建了一个表,并且表里面数据不能重复.
  初始化时在mysql中插入一条语句:
  insert into testdata(id,foo) values(1,1);
  然后在程序中处理:
  (1) 启动用户事务
  (2) 在oracle中插入语句insert into testdata(id,foo) values(1,1); --oracle是首次插入这个语句
  (3) 在mysql中重复插入数据
  (4) 如果一切正常提交事务,否则回滚事务
  分析: 假如不使用分布式事务,则oracle插入数据成功,mysql插入数据失败(重复插入).
  但是现在使用分布式事务,回滚时,导致oracle中的数据也回滚.
  所以上面4个步骤执行完毕后,oracle中仍然没有数据.
  测试代码:

package foo;
import java.sql.Statement;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import javax.transaction.UserTransaction;
public class DBTest
{
int foo = -1;
// value stored in DB
public void init(String completion)
{
UserTransaction ut = null;
try
{
Context ctx = new InitialContext();
// mysql数据源
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/mysqlDB");
//oracle数据源
DataSource dsOra = (DataSource) ctx.lookup("java:comp/env/jdbc/oracleDB");
//用户事务(分布式)
ut = (UserTransaction) ctx.lookup("java:comp/UserTransaction");

java.sql.Connection conn = ds.getConnection();
java.sql.Connection connOra = dsOra.getConnection();
System.out.println("<<< beginning the transaction >>>");
ut.begin();
//oracle中插入数据
Statement stmtOra =connOra.createStatement();
stmtOra.execute("insert into testdata(id,foo) values(1,1)");
// mysql中插入数据(之前表里面已经有一样的数据,导致下面的插入数据失败)
Statement stmt = conn.createStatement();
stmt.execute("insert into testdata(id,foo) values(1,1)");
//mysql 中插入失败导致整个事务回滚,oracle也回滚了,导致oracle中仍然没有数据.

System.out.println("<<< committing the transaction >>>");
ut.commit();
stmt.close();
stmtOra.close();
conn.close();
connOra.close();
System.out.println("<<< done >>>");
}
catch (Exception e)
{
try
{
System.out.println("<<< rollbacking the transaction >>>");
ut.rollback();
}
catch (Exception es)
{
System.out.println("rollbacking error >> ");
es.printStackTrace();
}
System.out.println("DBTest >> ");
e.printStackTrace();
}
}
public String getFoo()
{
return "" + foo;
}
}
  参考 :http://static.raibledesigns.com/downloads/howto-tomcat-jotm.html
  http://static.raibledesigns.com/downloads/howto-tomcat-jotm.html
  http://www.blogjava.net/nokiaguy/archive/2008/05/08/199150.html
  附件为工程文件,需要重新命名
  TestJomt001.7z 重命名 TestJomt.7z .001
  TestJomt002.7z 重命名 TestJomt.7z .002

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-338782-1-1.html 上篇帖子: 【转载】Tomcat 7.0.5x 启动慢并且遇到StackOverflowError的异常的解决办法 下篇帖子: Tomcat安装后运行出现“位于 XDB 的服务器 localhost 要求用户名和密码”
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表