spring+atomikos+JTA完整例子
看完了经乾的《TUXEDO系统经典》后,觉得tuxedo的事务处理功能是无比强大,当时心里就想如果能用JAVA来实现Tuxedo所有功能,那将是一个无比强大的分布式事务处理系统。当我看到atomikos时,我知我找到自己一心要寻找的事务处理工具。atomikos目前中文文档还很少,更没有完整的中文文档,本人读书甚少。没有能力能她的E文文档翻译成中文。今天是学习atomikos的第一天,终于把一个简单的例子做完,现在贴出来与大家共享,接下来俺要好好看她的E文文档了。applicationContext.xml配置
<!--
Atomikos JTA 事务 begin
-->
< bean id ="dataSource1" class ="com.atomikos.jdbc.SimpleDataSourceBean" init-method ="init" destroy-method ="close" >
< property name ="uniqueResourceName" >
< value > mysql/main </ value >
</ property >
< property name ="xaDataSourceClassName" >
<!-- 使用Mysql XADataSource(mysql>=5.0, Connector/J>=5.0才可以支持XADatasource) -->
< value > com.mysql.jdbc.jdbc2.optional.MysqlXADataSource </ value >
</ property >
< property name ="xaDataSourceProperties" >
< value > URL=jdbc:mysql://localhost:3306/test?useUnicode=true & characterEncoding=utf-8;user=root;password=123456 </ value >
</ property >
< property name ="exclusiveConnectionMode" >
< value > true </ value >
</ property >
< property name ="connectionPoolSize" >
< value > 3 </ value >
</ property >
< property name ="validatingQuery" >
< value > SELECT 1 </ value >
</ property >
</ bean >
< bean id ="dataSource2" class ="com.atomikos.jdbc.SimpleDataSourceBean" init-method ="init" destroy-method ="close" >
< property name ="uniqueResourceName" >
< value > mysql/secondary </ value >
</ property >
< property name ="xaDataSourceClassName" >
<!-- 使用Mysql XADataSource(mysql>=5.0, Connector/J>=5.0才可以支持XADatasource) -->
< value > com.mysql.jdbc.jdbc2.optional.MysqlXADataSource </ value >
</ property >
< property name ="xaDataSourceProperties" >
< value > URL=jdbc:mysql://localhost:3306/aotsf?useUnicode=true & characterEncoding=utf-8;user=root;password=123456 </ value >
</ property >
< property name ="exclusiveConnectionMode" >
< value > true </ value >
</ property >
< property name ="connectionPoolSize" >
< value > 3 </ value >
</ property >
< property name ="validatingQuery" >
< value > SELECT 1 </ value >
</ property >
</ bean >
< bean id ="atomikosTransactionManager" class ="com.atomikos.icatch.jta.UserTransactionManager" init-method ="init" destroy-method ="close" >
< property name ="forceShutdown" >< value > true </ value ></ property >
</ bean >
< bean id ="atomikosUserTransaction" class ="com.atomikos.icatch.jta.UserTransactionImp" >
< property name ="transactionTimeout" value ="300" />
</ bean >
< bean id ="springTransactionManager" class ="org.springframework.transaction.jta.JtaTransactionManager" >
< property name ="transactionManager" >
< ref bean ="atomikosTransactionManager" />
</ property >
< property name ="userTransaction" >
< ref bean ="atomikosUserTransaction" />
</ property >
</ bean >
< bean id ="atomikosTransactionProxy"
class ="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract ="true" >
< property name ="transactionManager" >
< ref bean ="springTransactionManager" />
</ property >
< property name ="transactionAttributes" >
< props >
< prop key ="*" > PROPAGATION_REQUIRED,-Exception </ prop >
</ props >
</ property >
</ bean >
< bean id ="jdbcBookDAO" class ="dao.jdbc.BookDAO" >
< property name ="dataSource" >
< ref bean ="dataSource1" />
</ property >
</ bean >
< bean id ="jdbcTestDAO" class ="dao.jdbc.TestDAO" >
< property name ="dataSource" >
< ref bean ="dataSource2" />
</ property >
</ bean >
< bean id ="atomikosJTAServiceDemo" parent ="atomikosTransactionProxy" >
< property name ="target" >
< bean class ="service.AtomikosJTAServiceDemo" >
< property name ="jdbcBookDAO" >
< ref bean ="jdbcBookDAO" />
</ property >
< property name ="jdbcTestDAO" >
< ref bean ="jdbcTestDAO" />
</ property >
</ bean >
</ property >
</ bean >
<!-- Atomikos JTA 事务 end -->
< bean id ="dataSource1" class ="com.atomikos.jdbc.SimpleDataSourceBean" init-method ="init" destroy-method ="close" >
< property name ="uniqueResourceName" >
< value > mysql/main </ value >
</ property >
< property name ="xaDataSourceClassName" >
<!-- 使用Mysql XADataSource(mysql>=5.0, Connector/J>=5.0才可以支持XADatasource) -->
< value > com.mysql.jdbc.jdbc2.optional.MysqlXADataSource </ value >
</ property >
< property name ="xaDataSourceProperties" >
< value > URL=jdbc:mysql://localhost:3306/test?useUnicode=true & characterEncoding=utf-8;user=root;password=123456 </ value >
</ property >
< property name ="exclusiveConnectionMode" >
< value > true </ value >
</ property >
< property name ="connectionPoolSize" >
< value > 3 </ value >
</ property >
< property name ="validatingQuery" >
< value > SELECT 1 </ value >
</ property >
</ bean >
< bean id ="dataSource2" class ="com.atomikos.jdbc.SimpleDataSourceBean" init-method ="init" destroy-method ="close" >
< property name ="uniqueResourceName" >
< value > mysql/secondary </ value >
</ property >
< property name ="xaDataSourceClassName" >
<!-- 使用Mysql XADataSource(mysql>=5.0, Connector/J>=5.0才可以支持XADatasource) -->
< value > com.mysql.jdbc.jdbc2.optional.MysqlXADataSource </ value >
</ property >
< property name ="xaDataSourceProperties" >
< value > URL=jdbc:mysql://localhost:3306/aotsf?useUnicode=true & characterEncoding=utf-8;user=root;password=123456 </ value >
</ property >
< property name ="exclusiveConnectionMode" >
< value > true </ value >
</ property >
< property name ="connectionPoolSize" >
< value > 3 </ value >
</ property >
< property name ="validatingQuery" >
< value > SELECT 1 </ value >
</ property >
</ bean >
< bean id ="atomikosTransactionManager" class ="com.atomikos.icatch.jta.UserTransactionManager" init-method ="init" destroy-method ="close" >
< property name ="forceShutdown" >< value > true </ value ></ property >
</ bean >
< bean id ="atomikosUserTransaction" class ="com.atomikos.icatch.jta.UserTransactionImp" >
< property name ="transactionTimeout" value ="300" />
</ bean >
< bean id ="springTransactionManager" class ="org.springframework.transaction.jta.JtaTransactionManager" >
< property name ="transactionManager" >
< ref bean ="atomikosTransactionManager" />
</ property >
< property name ="userTransaction" >
< ref bean ="atomikosUserTransaction" />
</ property >
</ bean >
< bean id ="atomikosTransactionProxy"
class ="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract ="true" >
< property name ="transactionManager" >
< ref bean ="springTransactionManager" />
</ property >
< property name ="transactionAttributes" >
< props >
< prop key ="*" > PROPAGATION_REQUIRED,-Exception </ prop >
</ props >
</ property >
</ bean >
< bean id ="jdbcBookDAO" class ="dao.jdbc.BookDAO" >
< property name ="dataSource" >
< ref bean ="dataSource1" />
</ property >
</ bean >
< bean id ="jdbcTestDAO" class ="dao.jdbc.TestDAO" >
< property name ="dataSource" >
< ref bean ="dataSource2" />
</ property >
</ bean >
< bean id ="atomikosJTAServiceDemo" parent ="atomikosTransactionProxy" >
< property name ="target" >
< bean class ="service.AtomikosJTAServiceDemo" >
< property name ="jdbcBookDAO" >
< ref bean ="jdbcBookDAO" />
</ property >
< property name ="jdbcTestDAO" >
< ref bean ="jdbcTestDAO" />
</ property >
</ bean >
</ property >
</ bean >
<!-- Atomikos JTA 事务 end -->
DAO层代码
package
dao.jdbc;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import domain.Book;
public class BookDAO extends JdbcDaoSupport{
public void addBook(Book book){
try {
JdbcTemplate jt = getJdbcTemplate();
String str_sql = " insert into Book(isbn,bookname,author,note)VALUES(?,?,?,?) " ;
String[] args = {book.getIsbn(),book.getBookname(),book.getAuthor(),book.getNote()};
jt.update(str_sql, args);
} catch (RuntimeException e){
System.out.println( " 添加Book失败
"
);
e.printStackTrace();
throw e;
}
}
}
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import domain.Book;
public class BookDAO extends JdbcDaoSupport{
public void addBook(Book book){
try {
JdbcTemplate jt = getJdbcTemplate();
String str_sql = " insert into Book(isbn,bookname,author,note)VALUES(?,?,?,?) " ;
String[] args = {book.getIsbn(),book.getBookname(),book.getAuthor(),book.getNote()};
jt.update(str_sql, args);
} catch (RuntimeException e){
System.out.println( " 添加Book失败

e.printStackTrace();
throw e;
}
}
}
package
dao.jdbc;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class TestDAO extends JdbcDaoSupport{
public void addBook(Integer id, String email){
try {
JdbcTemplate jt = getJdbcTemplate();
String str_sql = " insert into test(id,email)VALUES(?,?) " ;
Object[] args = {id,email};
jt.update(str_sql, args);
} catch (RuntimeException e){
System.out.println( " 添加Test失败
"
);
e.printStackTrace();
throw e;
}
}
}
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
public class TestDAO extends JdbcDaoSupport{
public void addBook(Integer id, String email){
try {
JdbcTemplate jt = getJdbcTemplate();
String str_sql = " insert into test(id,email)VALUES(?,?) " ;
Object[] args = {id,email};
jt.update(str_sql, args);
} catch (RuntimeException e){
System.out.println( " 添加Test失败

e.printStackTrace();
throw e;
}
}
}
事层代码
package
service;
import dao.jdbc.BookDAO;
import dao.jdbc.TestDAO;
import domain.Book;
public class AtomikosJTAServiceDemo {
private BookDAO jdbcBookDAO;
private TestDAO jdbcTestDAO;
public String ok(){
System.out.println( " 开始
.
"
);
jdbcTestDAO.addBook(Integer.valueOf( " 2 " ), " pdw2009 tom.com " );
Book book = new Book();
book.setIsbn( " ccdada66 " );
book.setAuthor( " 小东 " );
book.setNote( " JTA测试 " );
book.setBookname( " Atomikos学习 " );
jdbcBookDAO.addBook(book);
System.out.println( " 结束
.
"
);
return " ok " ;
}
public BookDAO getJdbcBookDAO() {
return jdbcBookDAO;
}
public void setJdbcBookDAO(BookDAO jdbcBookDAO) {
this .jdbcBookDAO = jdbcBookDAO;
}
public TestDAO getJdbcTestDAO() {
return jdbcTestDAO;
}
public void setJdbcTestDAO(TestDAO jdbcTestDAO) {
this .jdbcTestDAO = jdbcTestDAO;
}
}
测试用例
import dao.jdbc.BookDAO;
import dao.jdbc.TestDAO;
import domain.Book;
public class AtomikosJTAServiceDemo {
private BookDAO jdbcBookDAO;
private TestDAO jdbcTestDAO;
public String ok(){
System.out.println( " 开始

jdbcTestDAO.addBook(Integer.valueOf( " 2 " ), " pdw2009 tom.com " );
Book book = new Book();
book.setIsbn( " ccdada66 " );
book.setAuthor( " 小东 " );
book.setNote( " JTA测试 " );
book.setBookname( " Atomikos学习 " );
jdbcBookDAO.addBook(book);
System.out.println( " 结束

return " ok " ;
}
public BookDAO getJdbcBookDAO() {
return jdbcBookDAO;
}
public void setJdbcBookDAO(BookDAO jdbcBookDAO) {
this .jdbcBookDAO = jdbcBookDAO;
}
public TestDAO getJdbcTestDAO() {
return jdbcTestDAO;
}
public void setJdbcTestDAO(TestDAO jdbcTestDAO) {
this .jdbcTestDAO = jdbcTestDAO;
}
}
package
services;
import static org.junit.Assert. * ;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.AtomikosJTAServiceDemo;
public class AtomikosJTAServiceDemoTest {
ApplicationContext acx = null ;
AtomikosJTAServiceDemo atomikosJTAServiceDemo = null ;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
@Before
public void setUp() throws Exception {
acx = new ClassPathXmlApplicationContext( " applicationContext.xml " );
atomikosJTAServiceDemo = (AtomikosJTAServiceDemo) acx.getBean( " atomikosJTAServiceDemo " );
}
@After
public void tearDown() throws Exception {
}
@Test
public void notnullTest() throws Exception{
assertNotNull(atomikosJTAServiceDemo);
}
@Test
public void okTest() throws Exception{
assertEquals(atomikosJTAServiceDemo.ok(), " ok " );
}
}
import static org.junit.Assert. * ;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.AtomikosJTAServiceDemo;
public class AtomikosJTAServiceDemoTest {
ApplicationContext acx = null ;
AtomikosJTAServiceDemo atomikosJTAServiceDemo = null ;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
@Before
public void setUp() throws Exception {
acx = new ClassPathXmlApplicationContext( " applicationContext.xml " );
atomikosJTAServiceDemo = (AtomikosJTAServiceDemo) acx.getBean( " atomikosJTAServiceDemo " );
}
@After
public void tearDown() throws Exception {
}
@Test
public void notnullTest() throws Exception{
assertNotNull(atomikosJTAServiceDemo);
}
@Test
public void okTest() throws Exception{
assertEquals(atomikosJTAServiceDemo.ok(), " ok " );
}
}