好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

瞅瞅Infinispan事务管理源码是啥样的

瞅瞅Infinispan事务管理源码是啥样的

希望可以更直观地了解Infinispan的事务管理,(提一点Infinispan是遵循LGPL,具体开源协议参阅《 各种开源协议介绍 BSD、Apache Licence、GPL V2 、GPL V3 、LGPL、MIT 》)本文重点在JTA的使用

在上一篇《 Ehcache 事务管理源码探析 》中针对Ehcache的JTA事务管理说明了一番,是在JBoss服务器环境下使用JTA。同样在Infinispan中也具有获取JBoss容器事务管理器的能力,即配置事务查找器为 JBossTransactionManagerLookup,实现源码如下:

 /**  
* Uses JNDI to look-up the { @link TransactionManager} instance from "java:/TransactionManager".
*
* @author Bela Ban, Aug 26 2003
* @since 4.0
*/
public class JBossTransactionManagerLookup implements TransactionManagerLookup {

public TransactionManager getTransactionManager() throws Exception {
String as7Location = "java:jboss/TransactionManager";

InitialContext initialContext = new InitialContext();
try {
// Check for JBoss AS 7
return (TransactionManager) initialContext.lookup(as7Location);
} catch (NamingException ne) {
// Fall back and try for AS 4 ~ 6
String legacyAsLocation = "java:/TransactionManager";

try {
// Check for JBoss AS 4 ~ 6
return (TransactionManager) initialContext.lookup(legacyAsLocation);
} catch (NamingException neAgain) {
throw new ConfigurationException("Unable to locate a transaction manager in JNDI, either in " + as7Location + " or " + legacyAsLocation);
}

} finally {
Util.close(initialContext);
}
}
}

复制代码

在此就不再细说了,关键看另外一种在没有JBoss环境下的JTA事务管理该是怎样的。即配置Infinispan事务管理查找器为:JBossStandaloneJTAManagerLookup。看源码:

 /**  
* JTA standalone TM lookup.
*
* @author Jason T. Greene
* @since 4.0
*/
public class JBossStandaloneJTAManagerLookup implements TransactionManagerLookup {
private Method manager, user;
private static final Log log = LogFactory.getLog(JBossStandaloneJTAManagerLookup. class );

@Inject
public void init(Configuration configuration) {
// The TM may be deployed embedded alongside the app, so this needs to be looked up on the same CL as the Cache
try {
manager = Util.loadClass("com.arjuna.ats.jta.TransactionManager", configuration.getClassLoader()).getMethod("transactionManager");
user = Util.loadClass("com.arjuna.ats.jta.UserTransaction", configuration.getClassLoader()).getMethod("userTransaction");
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}

public TransactionManager getTransactionManager() throws Exception {
TransactionManager tm = (TransactionManager) manager.invoke( null );
if (log.isInfoEnabled()) log.retrievingTm(tm);
return tm;
}

public UserTransaction getUserTransaction() throws Exception {
return (UserTransaction) user.invoke( null );
}
}

复制代码

看上去似乎很简单,Infinispan使用该种方式也很简单,引入jbossjta.jar即可。如此对Infinispan缓存的事务管理功能就有了,但是有一个疑问,怎么与数据库的事务管理结合起来呢?我们知道之前《 JBoss下的JTA使用理解 》中借助JBoss容器只需配置数据源就可以了,这该怎么办呢?对事务类型有疑问可参看  事务处理总结(JDBC事务|JTA事务|容器事务 )

继续

让Infinispan使用JBoss JTA事务,引入jbossjta.jar,根据JTA规范,集成数据库的事务,应该让JDBC驱动实现JTA中参与者应该实现的接口,主要是XAResource,经测试MySQL JDBC驱动包括XA接口实现。之前是通过在JBoss中写好配置文件,从JNDI获取XA数据源,现在不借助JBoss容器,在应用中创建XADataSource,示例如下:

 package  database.mysql.xa;

import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;

/**
* @author yaohw
*
*/
public class XAUtil {

public static MysqlXADataSource getXADataSource(){
MysqlXADataSource xaDS = new MysqlXADataSource();
xaDS.setDatabaseName("mytest");
xaDS.setServerName("127.0.0.1");
xaDS.setPortNumber(3306);
xaDS.setUser("root");
xaDS.setPassword("root");
return xaDS;
}

public static void main(String[] args) {
MysqlXADataSource xaDS = getXADataSource();
System.out.println(xaDS);
}
}

复制代码

接着是重要的一步,该如何让JTA事务管理将该数据源的操作纳入到管理范围内。寻寻觅觅看到Transaction接口中有一个方法: boolean enlistResource(javax.transaction.xa.XAResource arg0),好!就是他了。同样还有一个相反的操作boolean delistResource(javax.transaction.xa.XAResource arg0, int arg1) 。

具体获取连接以及XAResource的方式就比较简单,不赘述。
接下来测试:

 try  {
tm.begin();
value = cache.get(key);
if (value == null ){
value = adminDAO.findAdminById(Integer.parseInt(key.toString()));
cache.put(key, value);
}
System.out.println("get after put :"+cache.get(key));
Admin a = new Admin();
a.setPassword("hello");
a.setUsername("boy");
adminDAO.addAdmin(a);

// rollback();
tm.commit();
System.out.println("get after rollback :"+cache.get(key));
} catch (Exception e1) {
e1.printStackTrace();
rollback();
}

复制代码

现在总算可以在离开JBoss的怀抱,数据库和缓存同生同灭了。

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于瞅瞅Infinispan事务管理源码是啥样的的详细内容...

  阅读:33次