Atomikos

    Atomikos是一个公司的名字,AtomikosTransactionsEssentials是其开源的分布式事务软件包,而ExtremeTransactions是商业的分布式事务软件包。TransactionsEssentials是基于apache-license的,是JTA/XA的开源实现,支持Java Application和J2EE应用。
    下面以AtomikosTransactionsEssentials-3.4.2(可以在http://www.atomikos.com下载)为例,说明其用法。
    需要的jar包:jta.jar、transactions-essentials-all.jar。

    Atomikos默认在classpath下使用名为transactions.properties的配置文件,如果找不到,则使用默认的配置参数。下面给一个transactions.properties的例子,可以根据自己的需要修改:

#SAMPLE PROPERTIES FILE FOR THE TRANSACTION SERVICE 
#THIS FILE ILLUSTRATES THE DIFFERENT SETTINGS FOR THE TRANSACTION MANAGER 
#UNCOMMENT THE ASSIGNMENTS TO OVERRIDE DEFAULT VALUES; 
#Required: factory class name for the transaction service core. 
# 
com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory 
# 
#Set name of file where messages are output 
# 
#com.atomikos.icatch.console_file_name = tm.out 
#Size limit (in bytes) for the console file; 
#negative means unlimited. 
# 
#com.atomikos.icatch.console_file_limit=-1 
#For size-limited console files, this option 
#specifies a number of rotating files to 
#maintain. 
# 
#com.atomikos.icatch.console_file_count=1 
#Set the number of log writes between checkpoints 
# 
#com.atomikos.icatch.checkpoint_interval=500 
#Set output directory where console file and other files are to be put 
#make sure this directory exists! 
# 
#com.atomikos.icatch.output_dir = ./ 
#Set directory of log files; make sure this directory exists! 
# 
#com.atomikos.icatch.log_base_dir = ./ 
#Set base name of log file 
#this name will be used as the first part of 
#the system-generated log file name 
# 
#com.atomikos.icatch.log_base_name = tmlog 
#Set the max number of active local transactions 
#or -1 for unlimited. 
# 
#com.atomikos.icatch.max_actives = 50 
#Set the max timeout (in milliseconds) for local transactions 
# 
#com.atomikos.icatch.max_timeout = 300000 
#The globally unique name of this transaction manager process 
#override this value with a globally unique name 
# 
#com.atomikos.icatch.tm_unique_name = tm 
#Do we want to use parallel subtransactions? JTA's default 
#is NO for J2EE compatibility. 
# 
#com.atomikos.icatch.serial_jta_transactions=true 
#If you want to do explicit resource registration then 
#you need to set this value to false. See later in 
#this manual for what explicit resource registration means. 
# 
#com.atomikos.icatch.automatic_resource_registration=true 
#Set this to WARN, INFO or DEBUG to control the granularity 
#of output to the console file. 
# 
#com.atomikos.icatch.console_log_level=WARN 
#Do you want transaction logging to be enabled or not? 
#If set to false, then no logging overhead will be done 
#at the risk of losing data after restart or crash. 
# 
#com.atomikos.icatch.enable_logging=true 
#Should two-phase commit be done in (multi-)threaded mode or not? 
# 
#com.atomikos.icatch.threaded_2pc=true 
#Should exit of the VM force shutdown of the transaction core? 
# 
#com.atomikos.icatch.force_shutdown_on_vm_exit=false 
#Should the logs be protected by a .lck file on startup? 
# 
#com.atomikos.icatch.lock_logs=true

Atomikos TransactionsEssentials支持3种使用方式,可以根据自己的情况选用,下面给出每种方式的使用场合和一个代码示例。
    一、使用JDBC/JMS和UserTransaction,这是最直接和最简单的使用方式,使用Atomikos内置的JDBC、JMS适配器。示例如下:
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.transaction.UserTransaction;

import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.jdbc.AtomikosDataSourceBean;

/** 
* 
*/
public class UserTransactionUtil {

	public static UserTransaction getUserTransaction() {
		UserTransaction utx = new UserTransactionImp();
		return utx;
	}

	private static AtomikosDataSourceBean dsBean;

	private static AtomikosDataSourceBean getDataSource() {
		if (dsBean != null)
			return dsBean;
		AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
		ds.setUniqueResourceName("db");
		ds.setXaDataSourceClassName("oracle.jdbc.xa.client.OracleXADataSource");
		Properties p = new Properties();
		p.setProperty("user", "db_user_name");
		p.setProperty("password", "db_user_pwd");
		p.setProperty("URL", "jdbc:oracle:thin:@192.168.0.10:1521:oradb");
		ds.setXaProperties(p);
		ds.setPoolSize(5);
		dsBean = ds;
		return dsBean;
	}

	public static Connection getDbConnection() throws SQLException {
		Connection conn = getDataSource().getConnection();
		return conn;
	}

	private static AtomikosDataSourceBean dsBean1;

	private static AtomikosDataSourceBean getDataSource1() {
		if (dsBean1 != null)
			return dsBean1;
		AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
		ds.setUniqueResourceName("db1");
		ds.setXaDataSourceClassName("oracle.jdbc.xa.client.OracleXADataSource");
		Properties p = new Properties();
		p.setProperty("user", "db_user_name");
		p.setProperty("password", "db_user_pwd");
		p.setProperty("URL", "jdbc:oracle:thin:@192.168.0.11:1521:oradb1");
		ds.setXaProperties(p);
		ds.setPoolSize(5);
		dsBean1 = ds;
		return dsBean1;
	}

	public static Connection getDb1Connection() throws SQLException {
		Connection conn = getDataSource1().getConnection();
		return conn;
	}

	public static void main(String[] args) {
		UserTransaction utx = getUserTransaction();
		boolean rollback = false;
		try {
			// begin a transaction
			utx.begin();

			// execute db operation
			Connection conn = null;
			Connection conn1 = null;
			Statement stmt = null;
			Statement stmt1 = null;
			try {
				conn = getDbConnection();
				conn1 = getDb1Connection();

				stmt = conn.createStatement();
				stmt.executeUpdate("insert into t values(1,'23')");

				stmt1 = conn1.createStatement();
				stmt1.executeUpdate("insert into t values(1,'123456789')");

			} catch (Exception e) {
				throw e;
			} finally {
				if (stmt != null)
					stmt.close();
				if (conn != null)
					conn.close();
				if (stmt1 != null)
					stmt1.close();
				if (conn1 != null)
					conn1.close();
			}
		} catch (Exception e) {
			// an exception means we should not commit
			rollback = true;
			e.printStackTrace();
		} finally {
			try {
				// commit or rollback the transaction
				if (!rollback)
					utx.commit();
				else
					utx.rollback();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}


    二、使用JTA TransactionManager。这种方式不需要Atomikos内置的JDBC、JMS适配器,但需要在JTA/XA级别上添加、删除XA资源实例。示例如下:
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.XAConnection;
import javax.transaction.Transaction;
import javax.transaction.xa.XAResource;

import oracle.jdbc.xa.client.OracleXADataSource;

import com.atomikos.icatch.jta.UserTransactionManager;

public class TransactionManagerUtil {
	public static UserTransactionManager getUserTransactionManager()
			throws Exception {
		return new UserTransactionManager();
	}

	private static OracleXADataSource xads;

	private static OracleXADataSource getXADataSource() throws SQLException {
		if (xads != null)
			return xads;
		xads = new OracleXADataSource();
		xads.setUser("db_user_name");
		xads.setPassword("db_user_pwd");
		xads.setURL("jdbc:oracle:thin:@192.168.0.10:1521:oradb");
		return xads;
	}

	public static XAConnection getXAConnection() throws SQLException {
		OracleXADataSource ds = getXADataSource();
		return ds.getXAConnection();
	}

	private static OracleXADataSource xads1;

	private static OracleXADataSource getXADataSource1() throws SQLException {
		if (xads1 != null)
			return xads1;
		xads1 = new OracleXADataSource();
		xads1.setUser("db_user_name");
		xads1.setPassword("db_user_pwd");
		xads1.setURL("jdbc:oracle:thin:@192.168.0.11:1521:oradb1");
		return xads1;
	}

	public static XAConnection getXAConnection1() throws SQLException {
		OracleXADataSource ds = getXADataSource1();
		return ds.getXAConnection();
	}

	public static void main(String[] args) {
		try {
			UserTransactionManager tm = getUserTransactionManager();

			XAConnection xaconn = getXAConnection();
			XAConnection xaconn1 = getXAConnection1();

			boolean rollback = false;
			try {
				// begin and retrieve tx
				tm.begin();
				Transaction tx = tm.getTransaction();

				// get the XAResourc from the JDBC connection
				XAResource xares = xaconn.getXAResource();
				XAResource xares1 = xaconn1.getXAResource();

				// enlist the resource with the transaction
				// NOTE: this will only work if you set the configuration
				// parameter:
				// com.atomikos.icatch.automatic_resource_registration=true
				// or, alternatively, if you use the UserTransactionService
				// integration mode
				tx.enlistResource(xares);
				tx.enlistResource(xares1);

				// access the database, the work will be
				// subject to the outcome of the current transaction
				Connection conn = xaconn.getConnection();
				Statement stmt = conn.createStatement();
				stmt.executeUpdate("insert into t values(1,'1234567')");
				stmt.close();
				conn.close();
				Connection conn1 = xaconn1.getConnection();
				Statement stmt1 = conn1.createStatement();
				stmt1.executeUpdate("insert into t values(1,'abc1234567890')");
				stmt1.close();
				conn1.close();

				// delist the resource
				tx.delistResource(xares, XAResource.TMSUCCESS);
				tx.delistResource(xares1, XAResource.TMSUCCESS);
			} catch (Exception e) {
				// an exception means we should not commit
				rollback = true;
				throw e;
			} finally {
				// ALWAYS terminate the tx
				if (rollback)
					tm.rollback();
				else
					tm.commit();

				// only now close the connection
				// i.e., not until AFTER commit or rollback!
				xaconn.close();
				xaconn1.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


三、使用Atomikos UserTransactionService。这是高级使用方式,可以控制事务服务的启动和关闭,并且可以控制资源的装配。示例如下:
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.XAConnection;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.xa.XAResource;

import oracle.jdbc.xa.client.OracleXADataSource;

import com.atomikos.datasource.xa.jdbc.JdbcTransactionalResource;
import com.atomikos.icatch.config.TSInitInfo;
import com.atomikos.icatch.config.UserTransactionService;
import com.atomikos.icatch.config.UserTransactionServiceImp;

public class UserTransactionServiceUtil {
	public static UserTransactionService getUserTransactionService()
			throws Exception {
		return new UserTransactionServiceImp();
	}

	private static OracleXADataSource xads;

	private static OracleXADataSource getXADataSource() throws SQLException {
		if (xads != null)
			return xads;
		xads = new OracleXADataSource();
		xads.setUser("db_user_name");
		xads.setPassword("db_user_pwd");
		xads.setURL("jdbc:oracle:thin:@192.168.0.10:1521:oradb");
		return xads;
	}

	public static XAConnection getXAConnection() throws SQLException {
		OracleXADataSource ds = getXADataSource();
		return ds.getXAConnection();
	}

	private static JdbcTransactionalResource jdbcResource;

	public static JdbcTransactionalResource getJdbcTransactionalResource()
			throws SQLException {
		if (jdbcResource != null)
			return jdbcResource;
		jdbcResource = new JdbcTransactionalResource("db", getXADataSource(),
				new com.atomikos.datasource.xa.OraXidFactory() // oracle db need
																// this
		);
		return jdbcResource;
	}

	private static OracleXADataSource xads1;

	private static OracleXADataSource getXADataSource1() throws SQLException {
		if (xads1 != null)
			return xads1;
		xads1 = new OracleXADataSource();
		xads1.setUser("db_user_name");
		xads1.setPassword("db_user_pwd");
		xads1.setURL("jdbc:oracle:thin:@192.168.0.11:1521:oradb1");
		return xads1;
	}

	public static XAConnection getXAConnection1() throws SQLException {
		OracleXADataSource ds = getXADataSource1();
		return ds.getXAConnection();
	}

	private static JdbcTransactionalResource jdbcResource1;

	public static JdbcTransactionalResource getJdbcTransactionalResource1()
			throws SQLException {
		if (jdbcResource1 != null)
			return jdbcResource1;
		jdbcResource1 = new JdbcTransactionalResource("db1",
				getXADataSource1(),
				new com.atomikos.datasource.xa.OraXidFactory() // oracle db need
																// this
		);
		return jdbcResource1;
	}

	public static void main(String[] args) {
		try {

			// Register the resource with the transaction service
			// this is done through the UserTransaction handle.
			// All UserTransaction instances are equivalent and each
			// one can be used to register a resource at any time.
			UserTransactionService uts = getUserTransactionService();
			uts.registerResource(getJdbcTransactionalResource());
			uts.registerResource(getJdbcTransactionalResource1());

			// Initialize the UserTransactionService.
			// This will start the TM and recover
			// all registered resources; you could
			// call this 'eager recovery' (as opposed to 'lazy recovery'
			// for the simple xa demo).
			TSInitInfo info = uts.createTSInitInfo();
			// optionally set config properties on info
			info.setProperty("com.atomikos.icatch.checkpoint_interval", "2000");
			uts.init(info);

			TransactionManager tm = uts.getTransactionManager();
			tm.setTransactionTimeout(60);

			XAConnection xaconn = getXAConnection();
			XAConnection xaconn1 = getXAConnection1();

			boolean rollback = false;

			// begin and retrieve tx
			tm.begin();
			Transaction tx = tm.getTransaction();

			// get the XAResourc from the JDBC connection
			XAResource xares = xaconn.getXAResource();
			XAResource xares1 = xaconn1.getXAResource();

			Connection conn = xaconn.getConnection();
			Connection conn1 = xaconn1.getConnection();
			try {

				// enlist the resource with the transaction
				// NOTE: this will only work if you set the configuration
				// parameter:
				// com.atomikos.icatch.automatic_resource_registration=true
				// or, alternatively, if you use the UserTransactionService
				// integration mode
				tx.enlistResource(xares);
				tx.enlistResource(xares1);

				// access the database, the work will be
				// subject to the outcome of the current transaction
				Statement stmt = conn.createStatement();
				stmt.executeUpdate("insert into t values(1,'1234567')");
				stmt.close();

				Statement stmt1 = conn1.createStatement();
				stmt1.executeUpdate("insert into t values(1,'abc')");
				stmt1.close();

			} catch (Exception e) {
				// an exception means we should not commit
				rollback = true;
				throw e;
			} finally {
				int flag = XAResource.TMSUCCESS;
				if (rollback)
					flag = XAResource.TMFAIL;

				tx.delistResource(xares, flag);
				tx.delistResource(xares1, flag);

				conn.close();
				conn1.close();

				if (!rollback)
					tm.commit();
				else
					tm.rollback();
			}

			uts.shutdown(false);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


在使用的时候,也可以把资源等配置到应用服务器中,使用JNDI获取资源。也可以与spring集成


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Atomikos TransactionsEssentials 是一个为Java平台提供增值服务的并且开源类事务管理器,以下是包括在这个开源版本中的一些功能: l 全面崩溃 / 重启恢复 l 兼容标准的SUN公司JTA API l 嵌套事务 l 为XA和非XA提供内置的JDBC适配器 注释:XA:XA协议由Tuxedo首先提出的,并交给X/Open组织,作为资源管理器(数据库)与事务管理器的接口标准。目前,Oracle、Informix、DB2和Sybase等各大数据库厂家都提供对XA的支持。XA协议采用两阶段提交方式来管理分布式事务。XA接口提供资源管理器与事务管理器之间进行通信的标准接口。XA协议包括两套函数,以xa_开头的及以ax_开头的。 以下的函数使事务管理器可以对资源管理器进行的操作: 1)xa_open,xa_close:建立和关闭与资源管理器的连接。 2)xa_start,xa_end:开始和结束一个本地事务。 3)xa_prepare,xa_commit,xa_rollback:预提交、提交和回滚一个本地事务。 4)xa_recover:回滚一个已进行预提交的事务。 5)ax_开头的函数使资源管理器可以动态地在事务管理器中进行注册,并可以对XID(TRANSACTION IDS)进行操作。 6)ax_reg,ax_unreg;允许一个资源管理器在一个TMS(TRANSACTION MANAGER SERVER)中动态注册或撤消注册。 l 内置的JMS适配器XA-capable JMS队列连接器 注释:JMS:jms即Java消息服务(Java Message Service)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。 l 通过XA API兼容第三方适配器 l 更好的整合您的项目 l 集成Hibernate 如何使用Atomikos TransactionsEssentials Atomikos TransactionsEssentials 是一个可靠的库,可以加入到您的Java应用程序,也就是说为了使用这个产品,您必须添加一些jar文件(包括在dist和lib文件夹下)到您的应用程序或者应用程序服务器。 请注意:Atomikos TransactionsEssentials是一个非常快速的嵌入式事务管理器,这就意味着,您不需要另外启动一个单独的事务管理器进程(不要查找任何的bin文件夹)。相反,您的应用服务器将有它自己的intra-VM事务管理器。 配置需求:至少Java1.5 jdk,并且最少128M的内存 性能优化:尽管这个软件有着很大的优势,但是想要更好的发挥其作用,可以按以下的方法优化: l 更高的内存,意味着更高的吞吐量(每秒的事务数目) l 使连接池尽可能的大 l 一旦你不需要的连接请马上关闭它们。不要把你的应用程序放在缓存里,让内部连接池为你做这些,这将促使更高效的连接使用 l 不要让活动的事务闲置:终止所有情况下的事务,尤其是在异常报错情况下的事务。这将减少数据库的锁定时间,并且最大效率的处理启用的使用。 如果想获取这些细节的更多信息,也要参阅文档说明部分。 值得注意的是,在我们所有的压力测试中,Atomikos TransactionsEssentials比J2EE的web容器更高效的吞吐量。这些测量值包括日志记录的高效的事务状态,同样,在我们所有的测量中,包括XA和non-XA,高效的效率是一样的。 在J2SE中使用Atomikos Transactions Essentials,只需要按以下步骤 将idst和lib中的jar包全部放入的项目中 创建或者自定义你应用的transactions.properties(或者jta.properties)文件(事务管理器的配置),然后将它放入到classpath中,安装文件夹中包涵一个实例文件;在properties文件中注释(#)后面的是默认值,取消一行并且改变默认值。
Spring Boot和Atomikos是两个独立的开源项目,可以在Spring Boot应用程序中一起使用。Spring Boot是一个用于创建Java应用程序的框架,它简化了开发过程并提供了各种开箱即用的功能和自动配置。Atomikos是一个事务管理器,它提供了分布式事务管理的能力。 在Spring Boot应用程序中使用Atomikos,你需要遵循以下步骤: 1. 添加Atomikos的依赖:在你的项目的构建文件(如pom.xml)中添加Atomikos的依赖。你可以通过Maven或Gradle来管理依赖。 2. 配置数据源:在Spring Boot应用程序的配置文件中,配置Atomikos数据源。你可以使用Atomikos提供的`AtomikosDataSourceBean`来创建数据源,并配置相关属性,如数据库连接信息、事务管理等。 3. 配置事务管理器:在Spring Boot应用程序的配置文件中,配置Atomikos事务管理器。你可以使用`JtaTransactionManager`来管理分布式事务,并将Atomikos数据源与事务管理器进行关联。 4. 使用分布式事务:在你的代码中,使用Spring Boot提供的`@Transactional`注解来标记需要进行分布式事务管理的方法。当方法执行时,事务管理器将自动开始、提交或回滚事务。 通过以上步骤,你就可以在Spring Boot应用程序中使用Atomikos实现分布式事务管理了。它可以帮助你在多个数据库或其他资源之间保持一致性,并确保事务的原子性、一致性、隔离性和持久性。 希望以上信息对你有所帮助!如果你有更多的问题,请继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值