阿里开源分布式事务框架fescar
从https://github.com/alibaba/fescar/releases下载服务器包,解压缩。
sh fescar-server.sh $ LISTEN_PORT $ PATH_FOR_PERSISTENT_DATA
例如
sh fescar-server.sh 8091 / home / admin / fescar / data /
这里使用fescar最新的版本0.3.0
registry.conf
registry {
# file nacos
type = "file"
nacos {
serverAddr = "localhost"
namespace = "public"
cluster = "default"
}
file {
name = "file.conf"
}
}
file.conf
transport {
# tcp udt unix-domain-socket
type = "TCP"
#NIO NATIVE
server = "NIO"
#enable heartbeat
heartbeat = true
#thread factory for netty
thread-factory {
boss-thread-prefix = "NettyBoss"
worker-thread-prefix = "NettyServerNIOWorker"
server-executor-thread-prefix = "NettyServerBizHandler"
share-boss-worker = false
client-selector-thread-prefix = "NettyClientSelector"
client-selector-thread-size = 1
client-worker-thread-prefix = "NettyClientWorkerThread"
# netty boss thread size,will not be used for UDT
boss-thread-size = 1
#auto default pin or 8
worker-thread-size = 8
}
}
service {
#vgroup->rgroup
vgroup_mapping.my_test_tx_group = "localRgroup"
#only support single node
localRgroup.grouplist = "10.8.80.222:9999"
#degrade current not support
enableDegrade = false
#disable
disable = false
}
client {
async.commit.buffer.limit = 10000
lock {
retry.internal = 10
retry.times = 30
}
}
fescar规划是可以使用各种注册中心和配置中心的,但是目前版本还没有支持,配置文件多数为预留项目,主要配置信息在file.conf中的srvice,主要配置项为
localRgroup.grouplist = "10.8.80.222:9999"设置fescar-server的地址
vgroup_mapping.my_test_tx_group = "localRgroup"中的my_test_tx_group为设置的事务组名称
在TM和RM项目中分别创建Spring自动配置文件FescarConfig.java
package cn.ktp.demo.config;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
import com.alibaba.fescar.rm.datasource.DataSourceProxy;
import com.alibaba.fescar.spring.annotation.GlobalTransactionScanner;
/**
* @Author: kris
* @Description fescar全局设置,对数据源进行增强
* @Date Created in 2019/3/14 10:28
*/
@Configuration
@Import(DruidDataSourceAutoConfigure.class)
public class FescarConfig {
/**
* 包装数据源代理,用于在执行SQL之前生成回退日志
* @Param: druidDataSource datasource bean instance
* @Return: DataSourceProxy datasource proxy
*/
@Bean
public DataSourceProxy dataSourceProxy(DataSource druidDataSource){
return new DataSourceProxy((DruidDataSource)druidDataSource);
}
/**
* 替换 mybatis 的sqlSessionFactory,用数据源代理替换自动装配的数据源
* @Param: dataSourceProxy fescar数据源代理
* @Return: SqlSessionFactory mybatic使用的数据源
*/
@Bean
public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSourceProxy);
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:/mapper/*.xml"));
factoryBean.setTransactionFactory(new JdbcTransactionFactory());
return factoryBean.getObject();
}
/**
* 初始化全局事务扫描器
*
* @Return: GlobalTransactionScanner
*/
@Bean
public GlobalTransactionScanner globalTransactionScanner(){
return new GlobalTransactionScanner("demo_service", "my_test_tx_group");
}
}
这里,我的数据库使用的是mysql,持久层使用mybatis,我需要对数据源进行包装以支持fescar分布式事务管理,因此在这里对数据源进行扩展。如果TM项目不需要访问数据库,可以去除数据源代理和SqlSeeionFactory的定义,记得连上面的Import一起去掉。
GlobalTransactionScanner向fescar服务注册TM和RM的id和分支事务组。
我这里提供了一个例子,authApi的addUser调用了authService的addUser方法和demoService的demo方法,这是一个分布式服务调用,而我要做的仅仅是在方法上给一个标签@GlobalTransactional
之后,我们就可以开始测试了,调用这个服务,抛出异常,然后去数据库查询,发现已经demo方法已经回滚,在DemoService的控制台可以得到以下内容
2019-03-14 16:14:24.139 INFO 29117 --- [atch_RMROLE_1_8] c.a.f.core.rpc.netty.RmMessageListener : onMessage:xid=10.8.80.222:9999:2005758210,branchId=2005758211,branchType=AT,resourceId=jdbc:mysql://10.8.80.222:3306/kris?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true,applicationData=null
2019-03-14 16:14:24.139 INFO 29117 --- [atch_RMROLE_1_8] com.alibaba.fescar.rm.RMHandlerAT : AT Branch rolling back: 10.8.80.222:9999:2005758210 2005758211 jdbc:mysql://10.8.80.222:3306/kris?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
2019-03-14 16:14:24.167 INFO 29117 --- [atch_RMROLE_1_8] com.alibaba.fescar.rm.RMHandlerAT : AT Branch rollback result: PhaseTwo_Rollbacked
2019-03-14 16:14:24.167 INFO 29117 --- [atch_RMROLE_1_8] c.a.fescar.core.rpc.netty.RmRpcClient : RmRpcClient sendResponse branchStatus=PhaseTwo_Rollbacked,result code =Success,getMsg =null
DemoService中的RM收到回滚消息,进行了事务回滚。
分布式事务变得如此简单,期待fescar的生产版本上线!
代码已上传至https://gitee.com/krisdevhome/ktp-main ,如果觉得好就点个赞把