1. 程式人生 > >使用nhmicro提供的micro-datasource嵌入式的解決微服務架構中分布式事務問題

使用nhmicro提供的micro-datasource嵌入式的解決微服務架構中分布式事務問題

微服務 nhmicro 分布式

應用原理:

使用micro-datasource數據源使事務與線程解耦,通過groupid在其他線程進行事務提交或回滾。

多個系統需要統一提交時,通過activemq發送提交消息(含有groupid),各系統收到消息後進行統一提交或回滾。

技術分享


micro-datasource數據源與Mybatis或hibernate或jdbcTemplate等orm框架可以整合使用

原理是micro-datasource包中提供了路由數據源方案,通過aop動態切換普通數據源和分布式數據源

使用普通數據源時仍接受傳統事務管理器管理

技術分享

jar包下載:

需要使用nh-micro-datasource.jar


依賴log4j.jar\org.springframework.beans.jar\org.springframework.aop.jar\org.springframework.core.jar\aopalliance.jar

<dependency>

<groupId

>com.github.jeffreyning</groupId>

<artifactId>nh-micro-datasource</artifactId>

<version>1.0.0-RELEASE</version>

</dependency>

jms通知功能需要使用nh-micro-datasource-msg.jar

依賴geronimo-j2ee-management.jar/geronimo-jms.jar/activemq-core.jar

<dependency>

<groupId>com.github.jeffreyning</

groupId>

<artifactId>nh-micro-datasource-msg</artifactId>

<version>1.0.0-RELEASE</version>

</dependency>



分布式數據源配置樣例:


<!– micro分布式數據源 -->

<bean id="local_xa_dataSource" class="com.nh.micro.datasource.MicroXaDataSourceFactory" factory-method="createDataSource" init-method=“init”>

<!– 多個micro分布式數據源實例時可設置不同的dataSourceId 默認為default -->

<constructor-arg value=“default”/>

<property name="url" value="${database.url}" />

<property name="username" value="${database.user}" />

<property name="password" value="${database.password}" />

<property name="minSize" value=“5" />

<property name="maxSize" value=“20" />

<property name=“dirverClassName” value=“com.mysql.jdbc.Driver” />

<property name=“validationQuery” value=“select ‘x‘ from dual” />

</bean>

<!-- micro動態切換數據源配置 -->

<bean id="dynamic_xa_dataSource" class="com.nh.micro.datasource.MicroDynamicDataSource" >

<property name="targetDataSources">

<map key-type="java.lang.String">

<!– 設置目標數據源為分布式事務數據源 -->

<entry key="local_xa_dataSource" value-ref="local_xa_dataSource"></entry>

</map>

</property>

<!-- 默認目標數據源為主庫普通數據源 -->

<property name="defaultTargetDataSource" ref="dataSource"/>

</bean>

<!-- define the Mybatis SqlSessionFactory -->

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

<!– Mybatis引入micro動態切換數據源實例 -->

<property name="dataSource" ref="dynamic_xa_dataSource"/>

<property name="typeAliasesPackage" value="foo.model"/>

</bean>

<aop:config>

<aop:pointcut id="testPointcut" expression="execution( * foo.repository.TestRep.*(..))"/>

<aop:advisor pointcut-ref="testPointcut" advice-ref="dataSourceAdvice"/>

</aop:config>





設置切換分布式數據源的aop:

<!– 設置service層或dao層aop用來動態切換數據源 -->

<bean class="com.nh.micro.datasource.DataSourceAdvice" id="dataSourceAdvice">

<property name="readMethodList">

<list>

</list>

</property>

</bean>

<aop:config>

<aop:pointcut id="testPointcut" expression="execution( * foo.repository.TestRep.*(..))"/>

<aop:advisor pointcut-ref="testPointcut" advice-ref="dataSourceAdvice"/>

</aop:config>

代碼中通過註解設置哪些方法需切換為分布式數據源:

//Mybatis的Dao接口代碼示例,使用@ChangeDataSource註解決定是否切換為分布式事務數據源

package foo.repository;

import java.util.Map;

import com.nh.micro.datasource.ChangeDataSource;

public interface TestRep {

@ChangeDataSource(name="local_xa_dataSource")

public int updateInfo(Map paramMap);

@ChangeDataSource(name="local_xa_dataSource")

public int insertInfo(Map paramMap);

}

執行過程樣例:

//設置xaGroupId和xaBranchId

MicroXaDataSource.setXid(groupId,branchId);

//從Spring中取dao接口對象調用相關業務方法

TestRep testRep=MicroContextHolder.getContext().getBean("testRep");

Map paramMap=new HashMap();

paramMap.put("meta_key", metaKey);

paramMap.put("id", id);

testRep.insertInfo(paramMap);

//可以在其他的線程中根據xaGroupId提交或回滾分布式事務

MicroXaDataSourceFactory.getDataSourceInstance(“default”).commit(groupid);

設置事務提交消息接收和發送對象:

//設置activemq發送對象,發送commit/rollback命令給其他系統

<bean class="com.nh.micro.datasource.msg.MicroDataSourceJmsReceiver" init-method="init">

<property name="jmsUrl" value="tcp://10.10.xx.xx:61616"></property>

</bean>

//通知其他系統提交的命令是(groupid為參數)

//commit

MicroDataSourceJmsSender.sendXaMsg("commit", groupId);

//rollback

MicroDataSourceJmsSender.sendXaMsg(“rollback", groupId);

//設置activemq接收對象,接收從其他系統發來的commit/rollback命令,MicroDataSourceJmsReceiver內部收到消息後會負責根據groupid提交或回滾事務

<bean class="com.nh.micro.datasource.msg.MicroDataSourceJmsSender">

<property name="jmsUrl" value="tcp://10.10.xx.xx:61616"></property>

</bean>


使用nhmicro提供的micro-datasource嵌入式的解決微服務架構中分布式事務問題