spring整合atomikos實現分布式事務的方法示例_分布式-分布式事務處理

 2023-10-06 阅读 28 评论 0

摘要:在之前的文章"如何合理的使用動態數據源"中,其實也提到了分布式事務相關的場景如:利用多數據源實現讀寫分離,但直接使用動態數據源頻繁其實是很消耗資源的,而且就是當業務service一個方法中的業務涉及到多數據源來回操作的時候會存在沒法

在之前的文章"如何合理的使用動態數據源"中,其實也提到了分布式事務相關的場景如:利用多數據源實現讀寫分離,但直接使用動態數據源頻繁其實是很消耗資源的,而且就是當業務service一個方法中的業務涉及到多數據源來回操作的時候會存在沒法保證事務的ACID,基于多數據源這個事務問題,找到了一個比較好的解決方案,能進行分布式的處理,還能保住事務的ACID,首先我們先了解一下什么事務?事務的四大特性分別都是什么意思?

事務:是一組SQL組成的"邏輯處理單元"。

原子性(Atomicity):原子性是指事務包含的所有操作要么全部成功,要么全部失敗回滾。

一致性(Consistency):一致性是指事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態,也就是說一個事務執行之前和執行之后都必須處于一致性狀態。

隔離性(Isolation):隔離性是當多個用戶并發訪問數據庫時,比如操作同一張表時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作所干擾,多個并發事務之間要相互隔離。

持久性(Durability):持久性是指一個事務一旦被提交了,那么對數據庫中的數據的改變就是永久性的,即便是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作。

1. 那什么是分布式事務?

其實簡單的理解就是為了保證"不同數據庫的數據的一致性"。

2. 分布式事務產生的場景"數據庫的分庫分表"和"SOA服務化"。

1386d089649e3574f2d784a959889d4b.png

e448c2afb680f59543b905647f122170.png

3. 那要想做到做的分布式事務,我們應當怎么做了,最好的辦法我們先去了解什么是XA協議。

65f99a7c9a58b1df156f8ef8fc5e6bf2.png

個人對上面文字理解如下(不一定對,只是個人的理解):

e731c2f779eefc2f5abf2989f7010db2.png

正確理解如下:

f9762a67534f727a595e606742663b0f.png

3. XA模式的優缺點:

優點:簡單,使用分布式成本低。

缺點:性能不理想,XA無法滿足高并發的場景,許多Nosql是不支持XA協議的。

4. 其實除了XA這種解決分布式事務的方法外,還有如下的解決方案,其他的解決方案等有時間再整理。

解決方案:XA,可靠性消息模式,TCC,補償模式

5. 重點來了,就是Atomikos了,Atomikos是一個為Java平臺提供的開源事務管理器。

主要功能:全面奔潰/重啟恢復,嵌套事務,為XA和非XA提供內置的JDBC適配器,是標準SUM公司的JTA API的實現。

6. 既然都已經介紹了Atomikos強大功能了,那我們一起搭建一個基于SSM框架的測試代碼,測試這個Atomikos的功能是不是都是吹的,核心配置如下:

pom.xml 配置如下:

<!-- 第一步:實現了XA協議的開源第三方支持包  -->
<dependency><groupId>com.atomikos</groupId><artifactId>atomikos-util</artifactId><version>3.7.0</version>
</dependency>
<dependency><groupId>com.atomikos</groupId><artifactId>transactions-jta</artifactId><version>3.7.0</version>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions</artifactId>
<version>3.7.0</version>
</dependency>
<dependency><groupId>com.atomikos</groupId><artifactId>transactions-api</artifactId><version>3.7.0</version>
</dependency>
<dependency><groupId>com.atomikos</groupId><artifactId>transactions-jdbc</artifactId><version>3.7.0</version>
</dependency>
<dependency><groupId>org.codehaus.btm</groupId><artifactId>btm</artifactId><version>2.1.4</version>
</dependency>
<!-- 第一步:實現了XA協議的開源第三方支持包  -->

config.properties 配置如下:

# =====================本地環境=====================
his.db.url=jdbc:mysql://localhost:3306/his?useUnicode=true&amp;characterEncoding=UTF-8
his.db.user=root
his.db.password=roothispay.db.url=jdbc:mysql://localhost:3306/his_pay?useUnicode=true&amp;characterEncoding=UTF-8
hispay.db.user=root
hispay.db.password=root
# =====================本地環境=====================

jta.properties 配置如下:

com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory
com.atomikos.icatch.console_file_name = tm.out
com.atomikos.icatch.log_base_name = tmlog
com.atomikos.icatch.tm_unique_name = com.atomikos.spring.jdbc.tm
com.atomikos.icatch.console_log_level = INFO
# out log
com.atomikos.icatch.output_dir=/hello/atomikos
com.atomikos.icatch.log_base_dir=/hello/atomikos
com.atomikos.icatch.serial_jta_transactions=false

spring-dispatcher.xml 核心配置如下:

<context:property-placeholder location="classpath:config.properties" />
<bean id="abstractXADataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init"destroy-method="close" abstract="true"><property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/><property name="poolSize" value="10" /><property name="minPoolSize" value="10"/><property name="maxPoolSize" value="30"/><property name="borrowConnectionTimeout" value="60"/><property name="reapTimeout" value="20"/><!-- 最大空閑時間 --><property name="maxIdleTime" value="60"/><property name="maintenanceInterval" value="60"/><property name="loginTimeout" value="60"/><property name="testQuery"><value>select 1</value></property>
</bean><!-- his數據源  -->
<bean id="hisDataSource" parent="abstractXADataSource"><!-- value只要兩個數據源不同就行,隨便取名 --><property name="uniqueResourceName" value="mysql/his" /><property name="xaDataSourceClassName"value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /><property name="xaProperties"><props><prop key="URL">${his.db.url}</prop><prop key="user">${his.db.user}</prop><prop key="password">${his.db.password}</prop><prop key="pinGlobalTxToPhysicalConnection">true</prop></props></property>
</bean><bean id="hispayDataSource" parent="abstractXADataSource"><!-- value只要兩個數據源不同就行,隨便取名 --><property name="uniqueResourceName" value="mysql/hispay" /><property name="xaDataSourceClassName"value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /><property name="xaProperties"><props><prop key="URL">${hispay.db.url}</prop><prop key="user">${hispay.db.user}</prop><prop key="password">${hispay.db.password}</prop><prop key="pinGlobalTxToPhysicalConnection">true</prop></props></property>
</bean><bean id="hisSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="hisDataSource" /><property name="mapperLocations" value="classpath:mybatis/xml/his/*Mapper.xml" />
</bean><bean id="hispaySqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="hispayDataSource" /><property name="mapperLocations" value="classpath:mybatis/xml/hispay/*Mapper.xml" />
</bean><bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"init-method="init" destroy-method="close"><!-- atomikosTransactionManager 這個事務管理器可以關閉事務true  --> <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="transactionManager"class="org.springframework.transaction.jta.JtaTransactionManager"><property name="transactionManager"><ref bean="atomikosTransactionManager"/></property><property name="userTransaction"><ref bean="atomikosUserTransaction"/></property><!-- 必須設置,否則程序出現異常 JtaTransactionManager does not support custom isolation levels by default --><property name="allowCustomIsolationLevels" value="true"/></bean><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="cn.edu.his.pay.mapper.his"/><property name="sqlSessionFactoryBeanName" value="hisSqlSessionFactory" />
</bean><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="cn.edu.his.pay.mapper.hispay"/><property name="sqlSessionFactoryBeanName" value="hispaySqlSessionFactory" />
</bean><!-- 一定要開啟注解事務支持  -->
<tx:annotation-driven transaction-manager="transactionManager"/>

總結:到這里Atomikos集成到SSM框架就算完成了,這篇文章就不進行詳細的,對于Atomikos(分布式事務管理框架)的特性,我會在下篇文章中寫測試代碼去分別測試Atomikos的強大功能。

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/3/122480.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息