Distributed Transaction Processing

Distributed Transaction Processing

        In the previous article " How to Use Dynamic Data Sources Reasonably ", I also mentioned scenarios related to distributed transactions, such as: using multiple data sources to achieve read-write separation, but using dynamic data sources frequently is actually very resource-intensive. Moreover, when the business in a method of business service involves multiple data sources back-and-forth operations, there will be ACIDs that cannot guarantee transactions. Based on the transaction problem of multiple data sources, a better solution has been found, which can perform distributed Processing, but also to keep the ACID of the transaction, first of all let's understand what transaction? What do the four characteristics of a transaction mean?

Transaction : It is a "logical processing unit" composed of a group of SQL.

Atomicity : Atomicity means that all operations contained in a transaction either succeed or fail and roll back.

Consistency : Consistency means that a transaction must change the database from one consistent state to another, that is, a transaction must be in a consistent state before and after execution.

Isolation : Isolation means that when multiple users access the database concurrently, such as when operating the same table, the transaction opened by the database for each user cannot be interfered by the operations of other transactions. isolated from each other.

Durability : Durability means that once a transaction is committed, the changes to the data in the database are permanent, and the operation of committing the transaction will not be lost even if the database system encounters a failure.

1. What is a distributed transaction?

In fact, the simple understanding is to ensure the "consistency of data in different databases".

2. The scenarios generated by distributed transactions are "database sub-database sub-table" and "SOA service".

3. In order to achieve distributed transactions, what should we do? The best way is to first understand what the XA protocol is.

Personal understanding of the above text is as follows (not necessarily correct, just personal understanding):

The correct understanding is as follows:

3. Advantages and disadvantages of XA mode:

Advantages: Simple, low cost to use distributed.

Disadvantages: The performance is not ideal, XA cannot meet high concurrency scenarios, and many Nosql do not support the XA protocol.

4. The key point is Atomikos, Atomikos is an open source transaction manager for the Java platform.

Main functions: comprehensive crash/restart recovery, nested transactions, built-in JDBC adapters for XA and non-XA, and implementation of standard SUM's JTA API.

5. Now that the powerful functions of Atomikos have been introduced, let's build a test code based on the SSM framework to test whether the functions of Atomikos are all blown. The core configuration is as follows:

pom.xml is configured as follows:

<!-- 第一步:实现了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 is configured as follows:

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

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

jta.properties is configured as follows:

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

The core configuration of spring-dispatcher.xml is as follows:

<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"/>

Summary: Even if the integration of Atomikos into the SSM framework is complete, this article will not go into detail. For the features of Atomikos (distributed transaction management framework), I will write test code in the next article to test the power of Atomikos separately. Function.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325299025&siteId=291194637