Atomikos TransactionsEssentials 是一個可靠的庫,能夠加入到您的Java應用程序,也就是說爲了使用這個產品,您必須添加一些jar文件(包括在dist和lib文件夾下)到您的應用程序或者應用程序服務器。java
原由:
小項目,沒有用分佈式,但要操做兩個數據庫。本覺得隨便用spring配置兩個數據源就搞定,查詢是沒問題,問題是有一個數據庫總是插不進數據。Google狂搜以後,大概瞭解到是事務控制的問題。我用的是spring的聲明式事務管理(<tx:annotation-driven/>)。用通常的數據源配置,只有一個數據源的事務生效,其它數據源只能讀不能寫。
有帖子說,要支持多數據源的事務,只能用JTA事務管理(沒用過 -_-||),並且應用服務器還不能是Tomcat(一直在用tomcat,不想換-_-!!),頭疼了。幸好後面還有說,有第三方的實現支持JTA事務管理,一是JOTM,一是Atomikos。只要用了其中一個,還能繼續用Tomcat。由於名字短,先考慮用JOTM。到官網一看,最後更新日期是2010年。。呃。。轉向Atomikos。在Atomikos的官網看看文檔,看看例子,邊作邊調試,一個下午下來,總算有點成果,高興之餘作個記錄。其中會涉及到一些概念,好比分佈式事務、JTA、XA,我都有搜來了解一下,因理解膚淺無法作記錄。下面只是記錄mysql
Atomikos TransactionsEssentials 是一個爲Java平臺提供增值服務的而且開源類事務管理器,如下是包括在這個開源版本中的一些功能:spring
l 全面崩潰 / 重啓恢復sql
l 兼容標準的SUN公司JTA API數據庫
l 嵌套事務api
l 爲XA和非XA提供內置的JDBC適配器tomcat
註釋:XA:XA協議由Tuxedo首先提出的,並交給X/Open組織,做爲資源管理器(數據庫)與事務管理器的接口標準。目前,Oracle、Informix、DB2和Sybase等各大數據庫廠家都提供對XA的支持。XA協議採用兩階段提交方式來管理分佈式事務。XA接口提供資源管理器與事務管理器之間進行通訊的標準接口。XA協議包括兩套函數,以xa_開頭的及以ax_開頭的。服務器
如下的函數使事務管理器能夠對資源管理器進行的操做:mybatis
1)xa_open,xa_close:創建和關閉與資源管理器的鏈接。app
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配合spring的使用方法:
一、依賴包
Atomikos的:
transactions-jdbc
transactions-jta
transactions-api
transactions
atomikos-utils
還有一個不要忘了,是jta的包。
用maven要簡單一點,只須要加入兩個依賴:
Xml代碼
<dependency> <groupId>com.atomikos</groupId> <artifactId>transactions-jdbc</artifactId> <version>3.7.0</version> </dependency> <dependency> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId> <version>1.1</version> </dependency>
二、配置數據源
這一步是比較重要的。要用AtomikosDataSourceBean,而不是之前用的鏈接池如dbcp。最好也用XA(這東西我還不太懂),注意jdbc的連接地址和登錄帳號與普通鏈接池的配置的格式不同。下面是一個mysql數據庫的配置舉例:
Xml代碼
<bean id="dataSource1" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close"> <property name="uniqueResourceName" value="ds1"/> <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/> <property name="xaProperties"> <props> <prop key="url">jdbc:mysql://localhost/test</prop> <prop key="user">test</prop> <prop key="password">test</prop> </props> </property> <property name="minPoolSize" value="10" /> <property name="maxPoolSize" value="100" /> <property name="borrowConnectionTimeout" value="30" /> <property name="testQuery" value="select 1" /> <property name="maintenanceInterval" value="60" /> </bean>
再來一個sybase的配置舉例:
Xml代碼
<bean id="dataSource2" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close"> <property name="uniqueResourceName" value="ds2"/> <property name="xaDataSourceClassName" value="com.sybase.jdbc3.jdbc.SybXADataSource"/> <property name="xaProperties"> <props> <prop key="serverName">192.168.1.10</prop> <prop key="portNumber">2638</prop> <prop key="databaseName">test</prop> <prop key="user">test</prop> <prop key="password">test</prop> </props> </property> <property name="minPoolSize" value="10" /> <property name="maxPoolSize" value="100" /> <property name="borrowConnectionTimeout" value="30" /> <property name="testQuery" value="select 1" /> <property name="maintenanceInterval" value="60" /> </bean>
三、使用數據源
這一步與平時好像沒什麼不同。我作例子的時候是用mybatis,配置以下:
Xml代碼
<bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource1"/> </bean> <bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource2"/> </bean>
固然,mybatis還要配置一下映射文件的自動掃描,這裏與atomikos無關:
Xml代碼
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="xx.xx;" /> <property name="sqlSessionFactory" ref="sqlSessionFactory1"/> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="yy.yy;" /> <property name="sqlSessionFactory" ref="sqlSessionFactory2"/> </bean>
用spring JdbcTemplate應該與普通使用沒什麼不一樣,用hibernate可能會有點不同,沒測試過。
四、配置jta事務管理
這是很關鍵的一步。原理我不太懂,例子以下:
Xml代碼
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager"> <bean class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close"> <property name="forceShutdown" value="true"/> </bean> </property> <property name="userTransaction"> <bean class="com.atomikos.icatch.jta.UserTransactionImp"/> </property> </bean>
固然,用spring的聲明式事務配置,再加上一行:
Xml代碼
<tx:annotation-driven/>
(注意,原本要配置transaction-manager屬性,如:<tx:annotation-driven transaction-manager="transactionManager"/>。這裏沒有配置是由於它的默認值是transactionManager)
五、atomikos的配置文件jta.properties 這個文件通常放在根路徑吧,與log4j.properties相似。jta.properties也可命名爲transactions.properties。若是不配置這個文件,項目也能啓動,由於幾乎全部配置項都有默認值。最好仍是配置了,詳細配置信息請查看:http://www.atomikos.com/Documentation/JtaProperties。 六、不論是用JdbcTemplate、mybatis仍是hibernate,應該均可以寫代碼來測試了。。