Seata源码—2.seata-samples项目介绍
大纲
1.seata-samples的配置文件和启动类
2.seata-samples业务服务启动时的核心工作
3.seata-samples库存服务的连接池配置
4.Seata对数据库连接池代理配置的分析
5.Dubbo RPC通信过程中传递全局事务XID
6.Seata跟Dubbo整合的Filter(基于SPI机制)
7.seata-samples的AT事务例子原理流程
8.Seata核心配置文件file.conf的内容介绍
1.seata-samples的配置文件和启动类
(1)seata-samples的测试步骤
(2)seata-samples用户服务的配置和启动类
(3)seata-samples库存服务的配置和启动类
(4)seata-samples订单服务的配置和启动类
(5)seata-samples业务服务的配置和启动类
示例仓库:
https://github.com/seata/seata-samples
示例代码的模块ID:seata-samples-dubbo
(1)seata-samples的测试步骤
步骤一:启动DubboAccountServiceStarter
步骤二:启动DubboStorageServiceStarter
步骤三:启动DubboOrderServiceStarter
步骤四:运行DubboBusinessTester
(2)seata-samples用户服务的配置和启动类
dubbo-account-service.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"><!-- 把jdbc.properties文件里的配置加载进来 --><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations" value="classpath:jdbc.properties"/></bean><!-- 将配置文件里的值注入到库存服务的数据库连接池accountDataSource中 --><bean name="accountDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"><property name="url" value="${jdbc.account.url}"/><property name="username" value="${jdbc.account.username}"/><property name="password" value="${jdbc.account.password}"/><property name="driverClassName" value="${jdbc.account.driver}"/><property name="initialSize" value="0"/><property name="maxActive" value="180"/><property name="minIdle" value="0"/><property name="maxWait" value="60000"/><property name="validationQuery" value="Select 'x' from DUAL"/><property name="testOnBorrow" value="false"/><property name="testOnReturn" value="false"/><property name="testWhileIdle" value="true"/><property name="timeBetweenEvictionRunsMillis" value="60000"/><property name="minEvictableIdleTimeMillis" value="25200000"/><property name="removeAbandoned" value="true"/><property name="removeAbandonedTimeout" value="1800"/><property name="logAbandoned" value="true"/><property name="filters" value="mergeStat"/></bean><!-- 创建数据库连接池代理,通过DataSourceProxy代理accountDataSourceProxy数据库连接池 --><bean id="accountDataSourceProxy" class="io.seata.rm.datasource.DataSourceProxy"><constructor-arg ref="accountDataSource"/></bean><!-- 将数据库连接池代理accountDataSourceProxy注入到JdbcTemplate数据库操作组件中--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="accountDataSourceProxy"/></bean><dubbo:application name="dubbo-demo-account-service"><dubbo:parameter key="qos.enable" value="false"/></dubbo:application><dubbo:registry address="zookeeper://localhost:2181" /><dubbo:protocol name="dubbo" port="20881"/><dubbo:service interface="io.seata.samples.dubbo.service.AccountService" ref="service" timeout="10000"/><!-- 将JdbcTemplate数据库操作组件注入到AccountServiceImpl中 --><bean id="service" class="io.seata.samples.dubbo.service.impl.AccountServiceImpl"><property name="jdbcTemplate" ref="jdbcTemplate"/></bean><!-- 全局事务注解扫描组件 --><bean class="io.seata.spring.annotation.GlobalTransactionScanner"><constructor-arg value="dubbo-demo-account-service"/><constructor-arg value="my_test_tx_group"/></bean>
</beans>
启动类:
public class DubboAccountServiceStarter {//Account service is ready. A buyer register an account: U100001 on my e-commerce platformpublic static void main(String[] args) {ClassPathXmlApplicationContext accountContext = new ClassPathXmlApplicationContext(new String[] {"spring/dubbo-account-service.xml"});accountContext.getBean("service");JdbcTemplate accountJdbcTemplate = (JdbcTemplate)accountContext.getBean("jdbcTemplate");accountJdbcTemplate.update("delete from account_tbl where user_id = 'U100001'");accountJdbcTemplate.update("insert into account_tbl(user_id, money) values ('U100001', 999)");new ApplicationKeeper(accountContext).keep();}
}//The type Application keeper.
public class ApplicationKeeper {private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationKeeper.class);private final ReentrantLock LOCK = new ReentrantLock();private final Condition STOP = LOCK.newCondition();//Instantiates a new Application keeper.public ApplicationKeeper(AbstractApplicationContext applicationContext) {addShutdownHook(applicationContext);}private void addShutdownHook(final AbstractApplicationContext applicationContext) {Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {@Overridepublic void run() {try {applicationContext.close();LOGGER.info("ApplicationContext " + applicationContext + " is closed.");} catch (Exception e) {LOGGER.error("Failed to close ApplicationContext", e);}LOCK.lock();try {STOP.signal();} finally {LOCK.unlock();}}}));}public void keep() {LOCK.lock();try {LOGGER.info("Application is keep running ... ");STOP.await();} catch (InterruptedException e) {LOGGER.error("ApplicationKeeper.keep() is interrupted by InterruptedException!", e);} finally {LOCK.unlock();}}
}
(3)seata-samples库存服务的配置和启动类
dubbo-stock-service.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"><!-- 把jdbc.properties文件里的配置加载进来 --><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations" value="classpath:jdbc.properties"/></bean><!-- 将配置文件里的值注入到库存服务的数据库连接池stockDataSource中 --><bean name="stockDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"><property name="url" value="${jdbc.stock.url}"/><property name="username" value="${jdbc.stock.username}"/><property name="password" value="${jdbc.stock.password}"/><property name="driverClassName" value="${jdbc.stock.driver}"/><property name="initialSize" value="0"/><property name="maxActive" value="180"/><property name="minIdle" value="0"/><property name="maxWait" value="60000"/><property name="validationQuery" value="Select 'x' from DUAL"/><property name="testOnBorrow" value="false"/><property name="testOnReturn" value="false"/><property name="testWhileIdle" value="true"/><property name="timeBetweenEvictionRunsMillis" value="60000"/><property name="minEvictableIdleTimeMillis" value="25200000"/><property name="removeAbandoned" value="true"/><property name="removeAbandonedTimeout" value="1800"/><property name="logAbandoned" value="true"/><property name="filters" value="mergeStat"/></bean><!-- 创建数据库连接池代理,通过DataSourceProxy代理stockDataSource数据库连接池 --><bean id="stockDataSourceProxy" class="io.seata.rm.datasource.DataSourceProxy"><constructor-arg ref="stockDataSource"/></bean><!-- 将数据库连接池代理stockDataSourceProxy注入到JdbcTemplate数据库操作组件中--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="stockDataSourceProxy"/></bean><dubbo:application name="dubbo-demo-stock-service"><dubbo:parameter key="qos.enable" value="false"/></dubbo:application><dubbo:registry address="zookeeper://localhost:2181" /><dubbo:protocol name="dubbo" port="20882"/><dubbo:service interface="io.seata.samples.dubbo.service.StockService" ref="service" timeout="10000"/><!-- 将JdbcTemplate数据库操作组件注入到StockServiceImpl中 --><bean id="service" class="io.seata.samples.dubbo.service.impl.StockServiceImpl"><property name="jdbcTemplate" ref="jdbcTemplate"/></bean><!-- 全局事务注解扫描组件 --><bean class="io.seata.spring.annotation.GlobalTransactionScanner"><constructor-arg value="dubbo-demo-stock-service"/><constructor-arg value="my_test_tx_group"/></bean>
</beans>
启动类:
//The type Dubbo stock service starter.
public class DubboStockServiceStarter {//Stock service is ready. A seller add 100 stock to a sku: C00321public static void main(String[] args) {ClassPathXmlApplicationContext stockContext = new ClassPathXmlApplicationContext(new String[] {"spring/dubbo-stock-service.xml"});stockContext.getBean("service");JdbcTemplate stockJdbcTemplate = (JdbcTemplate)stockContext.getBean("jdbcTemplate");stockJdbcTemplate.update("delete from stock_tbl where commodity_code = 'C00321'");stockJdbcTemplate.update("insert into stock_tbl(commodity_code, count) values ('C00321', 100)");new ApplicationKeeper(stockContext).keep();}
}
(4)seata-samples订单服务的配置和启动类
dubbo-order-service.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"><!-- 把jdbc.properties文件里的配置加载进来 --><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations" value="classpath:jdbc.properties"/></bean><!-- 将配置文件里的值注入到库存服务的数据库连接池orderDataSource中 --><bean name="orderDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"><property name="url" value="${jdbc.order.url}"/><property name="username" value="${jdbc.order.username}"/><property name="password" value="${jdbc.order.password}"/><property name="driverClassName" value="${jdbc.order.driver}"/><property name="initialSize" value="0"/><property name="maxActive" value="180"/><property name="minIdle" value="0"/><property name="maxWait" value="60000"/><property name="validationQuery" value="Select 'x' from DUAL"/><property name="testOnBorrow" value="false"/><property name="testOnReturn" value="false"/><property name="testWhileIdle" value="true"/><property name="timeBetweenEvictionRunsMillis" value="60000"/><property name="minEvictableIdleTimeMillis" value="25200000"/><property name="removeAbandoned" value="true"/><property name="removeAbandonedTimeout" value="1800"/><property name="logAbandoned" value="true"/><property name="filters" value="mergeStat"/></bean><!-- 创建数据库连接池代理,通过DataSourceProxy代理stockDataSource数据库连接池 --><bean id="orderDataSourceProxy" class="io.seata.rm.datasource.DataSourceProxy"><constructor-arg ref="orderDataSource"/></bean><!-- 将数据库连接池代理orderDataSourceProxy注入到JdbcTemplate数据库操作组件中--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="orderDataSourceProxy"/></bean><dubbo:application name="dubbo-demo-order-service"><dubbo:parameter key="qos.enable" value="false"/></dubbo:application><dubbo:registry address="zookeeper://localhost:2181" /><dubbo:protocol name="dubbo" port="20883"/><dubbo:service interface="io.seata.samples.dubbo.service.OrderService" ref="service" timeout="10000"/><dubbo:reference id="accountService" check="false" interface="io.seata.samples.dubbo.service.AccountService"/><!-- 将JdbcTemplate数据库操作组件注入到OrderServiceImpl中 --><bean id="service" class="io.seata.samples.dubbo.service.impl.OrderServiceImpl"><property name="jdbcTemplate" ref="jdbcTemplate"/><property name="accountService" ref="accountService"/></bean><!-- 全局事务注解扫描组件 --><bean class="io.seata.spring.annotation.GlobalTransactionScanner"><constructor-arg value="dubbo-demo-order-service"/><constructor-arg value="my_test_tx_group"/></bean>
</beans>
启动类:
//The type Dubbo order service starter.
public class DubboOrderServiceStarter {//The entry point of application.public static void main(String[] args) {//Order service is ready . Waiting for buyers to orderClassPathXmlApplicationContext orderContext = new ClassPathXmlApplicationContext(new String[] {"spring/dubbo-order-service.xml"});orderContext.getBean("service");new ApplicationKeeper(orderContext).keep();}
}
(5)seata-samples业务服务的配置和启动类
dubbo-business.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"><dubbo:application name="dubbo-demo-app"><dubbo:parameter key="qos.enable" value="false"/><dubbo:parameter key="qos.accept.foreign.ip" value="false"/><dubbo:parameter key="qos.port" value="33333"/></dubbo:application><dubbo:registry address="zookeeper://localhost:2181" /><dubbo:reference id="orderService" check="false" interface="io.seata.samples.dubbo.service.OrderService"/><dubbo:reference id="stockService" check="false" interface="io.seata.samples.dubbo.service.StockService"/><bean id="business" class="io.seata.samples.dubbo.service.impl.BusinessServiceImpl"><property name="orderService" ref="orderService"/><property name="stockService" ref="stockService"/></bean><!-- 全局事务注解扫描组件 --><bean class="io.seata.spring.annotation.GlobalTransactionScanner"><constructor-arg value="dubbo-demo-app"/><constructor-arg value="my_test_tx_group"/></bean>
</beans>
启动类:
//The type Dubbo business tester.
public class DubboBusinessTester {//The entry point of application.public static void main(String[] args) {//The whole e-commerce platform is ready, The buyer(U100001) create an order on the sku(C00321) , the count is 2ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"spring/dubbo-business.xml"});//模拟调用下单接口final BusinessService business = (BusinessService)context.getBean("business");business.purchase("U100001", "C00321", 2);}
}
2.seata-samples业务服务启动时的核心工作
BusinessService业务服务启动时,会创建两个服务接口的动态代理。一个是OrderService订单服务接口的Dubbo动态代理,另一个是StockService库存服务接口的Dubbo动态代理。BusinessService业务服务的下单接口会添加@GlobalTransaction注解,通过@GlobalTransaction注解开启一个分布式事务,Seata的内核组件GlobalTransactionScanner就会扫描到这个注解。
//The type Dubbo business tester.
public class DubboBusinessTester {//The entry point of application.public static void main(String[] args) {//The whole e-commerce platform is ready , The buyer(U100001) create an order on the sku(C00321) , the count is 2ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"spring/dubbo-business.xml"});//模拟调用下单接口final BusinessService business = (BusinessService)context.getBean("business");business.purchase("U100001", "C00321", 2);}
}public class BusinessServiceImpl implements BusinessService {private static final Logger LOGGER = LoggerFactory.getLogger(BusinessService.class);private StockService stockService;private OrderService orderService;private Random random = new Random();@Override@GlobalTransactional(timeoutMills = 300000, name = "dubbo-demo-tx")//分布式事务如果5分钟还没跑完,就是超时public void purchase(String userId, String commodityCode, int orderCount) {LOGGER.info("purchase begin ... xid: " + RootContext.getXID());stockService.deduct(commodityCode, orderCount);orderService.create(userId, commodityCode, orderCount);if (random.nextBoolean()) {throw new RuntimeException("random exception mock!");}}//Sets stock service.public void setStockService(StockService stockService) {this.stockService = stockService;}//Sets order service.public void setOrderService(OrderService orderService) {this.orderService = orderService;}
}
3.seata-samples库存服务的连接池配置
首先会把jdbc.properties文件里的配置加载进来,然后将配置配置的值注入到库存服务的数据库连接池,接着通过Seata的DataSourceProxy对数据库连接池进行代理。
一.启动类
//The type Dubbo stock service starter.
public class DubboStockServiceStarter {//Stock service is ready. A seller add 100 stock to a sku: C00321public static void main(String[] args) {ClassPathXmlApplicationContext stockContext = new ClassPathXmlApplicationContext(new String[] {"spring/dubbo-stock-service.xml"});stockContext.getBean("service");JdbcTemplate stockJdbcTemplate = (JdbcTemplate)stockContext.getBean("jdbcTemplate");stockJdbcTemplate.update("delete from stock_tbl where commodity_code = 'C00321'");stockJdbcTemplate.update("insert into stock_tbl(commodity_code, count) values ('C00321', 100)");new ApplicationKeeper(stockContext).keep();}
}
二.dubbo-stock-service.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"><!-- 把jdbc.properties文件里的配置加载进来 --><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations" value="classpath:jdbc.properties"/></bean><!-- 将配置文件里的值注入到库存服务的数据库连接池stockDataSource中 --><bean name="stockDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"><property name="url" value="${jdbc.stock.url}"/><property name="username" value="${jdbc.stock.username}"/><property name="password" value="${jdbc.stock.password}"/><property name="driverClassName" value="${jdbc.stock.driver}"/><property name="initialSize" value="0"/><property name="maxActive" value="180"/><property name="minIdle" value="0"/><property name="maxWait" value="60000"/><property name="validationQuery" value="Select 'x' from DUAL"/><property name="testOnBorrow" value="false"/><property name="testOnReturn" value="false"/><property name="testWhileIdle" value="true"/><property name="timeBetweenEvictionRunsMillis" value="60000"/><property name="minEvictableIdleTimeMillis" value="25200000"/><property name="removeAbandoned" value="true"/><property name="removeAbandonedTimeout" value="1800"/><property name="logAbandoned" value="true"/><property name="filters" value="mergeStat"/></bean><!-- 创建数据库连接池代理,通过DataSourceProxy代理stockDataSource数据库连接池 --><bean id="stockDataSourceProxy" class="io.seata.rm.datasource.DataSourceProxy"><constructor-arg ref="stockDataSource"/></bean><!-- 将数据库连接池代理stockDataSourceProxy注入到JdbcTemplate数据库操作组件中--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="stockDataSourceProxy"/></bean><dubbo:application name="dubbo-demo-stock-service"><dubbo:parameter key="qos.enable" value="false"/></dubbo:application><dubbo:registry address="zookeeper://localhost:2181" /><dubbo:protocol name="dubbo" port="20882"/><dubbo:service interface="io.seata.samples.dubbo.service.StockService" ref="service" timeout="10000"/><!-- 将JdbcTemplate数据库操作组件注入到StockServiceImpl中 --><bean id="service" class="io.seata.samples.dubbo.service.impl.StockServiceImpl"><property name="jdbcTemplate" ref="jdbcTemplate"/></bean><!-- 全局事务注解扫描组件 --><bean class="io.seata.spring.annotation.GlobalTransactionScanner"><constructor-arg value="dubbo-demo-stock-service"/><constructor-arg value="my_test_tx_group"/></bean>
</beans>
三.jdbc.properties文件文件
jdbc.account.url=jdbc:mysql://localhost:3306/seata
jdbc.account.username=root
jdbc.account.password=123456
jdbc.account.driver=com.mysql.jdbc.Driver
# stock db config
jdbc.stock.url=jdbc:mysql://localhost:3306/seata
jdbc.stock.username=root
jdbc.stock.password=123456
jdbc.stock.driver=com.mysql.jdbc.Driver
# order db config
jdbc.order.url=jdbc:mysql://localhost:3306/seata
jdbc.order.username=root
jdbc.order.password=123456
jdbc.order.driver=com.mysql.jdbc.Driver
4.Seata对数据库连接池代理配置的分析
数据库连接池代理DataSourceProxy,会注入到JdbcTemplate数据库操作组件中。这样库存或者订单服务就可以通过Spring数据库操作组件JdbcTemplate,向Seata数据库连接池代理DataSourceProxy获取一个数据库连接。然后通过数据库连接,把SQL请求发送给MySQL进行处理。
5.Dubbo RPC通信过程中传递全局事务XID
BusinessService对StockService进行RPC调用时,会传递全局事务XID。StockService便可以根据RootContext.getXID()获取到全局事务XID。
public class BusinessServiceImpl implements BusinessService {private static final Logger LOGGER = LoggerFactory.getLogger(BusinessService.class);private StockService stockService;private OrderService orderService;private Random random = new Random();@Override@GlobalTransactional(timeoutMills = 300000, name = "dubbo-demo-tx")//分布式事务如果5分钟还没跑完,就是超时public void purchase(String userId, String commodityCode, int orderCount) {LOGGER.info("purchase begin ... xid: " + RootContext.getXID());stockService.deduct(commodityCode, orderCount);orderService.create(userId, commodityCode, orderCount);if (random.nextBoolean()) {throw new RuntimeException("random exception mock!");}}...
}public class StockServiceImpl implements StockService {private static final Logger LOGGER = LoggerFactory.getLogger(StockService.class);private JdbcTemplate jdbcTemplate;@Overridepublic void deduct(String commodityCode, int count) {LOGGER.info("Stock Service Begin ... xid: " + RootContext.getXID());LOGGER.info("Deducting inventory SQL: update stock_tbl set count = count - {} where commodity_code = {}", count, commodityCode);jdbcTemplate.update("update stock_tbl set count = count - ? where commodity_code = ?", new Object[] {count, commodityCode});LOGGER.info("Stock Service End ... ");}...
}
6.Seata跟Dubbo整合的Filter(基于SPI机制)
Seata与Dubbo整合的Filter过滤器ApacheDubboTransactionPropagationFilter会将向SeataServer注册的全局事务xid,设置到RootContext中。
7.seata-samples的AT事务例子原理流程
8.Seata核心配置文件file.conf的内容介绍
# Seata网络通信相关的配置
transport {# 网络通信的类型是TCPtype = "TCP"# 网络服务端使用NIO模式server = "NIO"# 是否开启心跳heartbeat = true# 是否允许Seata的客户端批量发送请求enableClientBatchSendRequest = true# 使用Netty进行网络通信时的线程配置threadFactory {bossThreadPrefix = "NettyBoss"workerThreadPrefix = "NettyServerNIOWorker"serverExecutorThread-prefix = "NettyServerBizHandler"shareBossWorker = falseclientSelectorThreadPrefix = "NettyClientSelector"clientSelectorThreadSize = 1clientWorkerThreadPrefix = "NettyClientWorkerThread"# 用来监听和建立网络连接的Boss线程的数量bossThreadSize = 1# 默认的Worker线程数量是8workerThreadSize = "default"}shutdown {# 销毁服务端的时候的等待时间是多少秒wait = 3}# 序列化类型是Seataserialization = "seata"# 是否开启压缩compressor = "none"
}# Seata服务端相关的配置
service {# 分布式事务的分组vgroupMapping.my_test_tx_group = "default"# only support when registry.type=file, please don't set multiple addressesdefault.grouplist = "127.0.0.1:8091"# 是否开启降级enableDegrade = false# 是否禁用全局事务disableGlobalTransaction = false
}# Seata客户端相关的配置
client {# 数据源管理组件的配置rm {# 异步提交缓冲区的大小asyncCommitBufferLimit = 10000# 锁相关的配置:重试间隔、重试次数、回滚冲突处理lock {retryInterval = 10retryTimes = 30retryPolicyBranchRollbackOnConflict = true}reportRetryCount = 5tableMetaCheckEnable = falsereportSuccessEnable = false}# 事务管理组件的配置tm {commitRetryCount = 5rollbackRetryCount = 5}# 回滚日志的配置undo {dataValidation = truelogSerialization = "jackson"logTable = "undo_log"}# log日志的配置log {exceptionRate = 100}
}
相关文章:
Seata源码—2.seata-samples项目介绍
大纲 1.seata-samples的配置文件和启动类 2.seata-samples业务服务启动时的核心工作 3.seata-samples库存服务的连接池配置 4.Seata对数据库连接池代理配置的分析 5.Dubbo RPC通信过程中传递全局事务XID 6.Seata跟Dubbo整合的Filter(基于SPI机制) 7.seata-samples的AT事…...
企业数字化转型背景下的企业知识管理挑战与经验杂谈
一、引言 在数字化转型的浪潮下,企业知识管理正面临前所未有的挑战。随着数据量的急剧增长,企业内部积累的信息呈现出碎片化、分散化的趋势,传统的知识管理体系已难以有效应对这一变革。首先,信息碎片化问题日益严重,…...
第二章:磁盘管理与文件管理
一、磁盘管理 1.windows和Linux磁盘管理的区别 windows资源管理方式 系统一般安装在C盘 C盘下的"Windows"目录是操作系统的核心 C盘下的"Program Files"目录下安装软件 C盘下的"用户"目录是所有的用户,包括超级管理员也在其中 …...
Java版OA管理系统源码 手机版OA系统源码
Java版OA管理系统源码 手机版OA系统源码 一:OA系统的主要优势 1. 提升效率 减少纸质流程和重复性工作,自动化处理常规事务,缩短响应时间。 2. 降低成本 节省纸张、打印、通讯及人力成本,优化资源分配。 3. 规范管理 固化企…...
springboot踩坑记录
之前运行好端端的项目,今天下午打开只是添加了一个文件之后 再运行都报Failed to configure a DataSource: url attribute is not specified and no embedded datasource could be configured.Reason: Failed to determine a suitable driver class Action: Conside…...
SpringAI
机器学习: 定义:人工智能的子领域,通过数据驱动的方法让计算机学习规律,进行预测或决策。 核心方法: 监督学习(如线性回归、SVM)。 无监督学习(如聚类、降维)。 强化学…...
acwing 1488. 最短距离 超级源点 最短路 堆优化Dijkstra
经验总结 邻接表 节点1连接到节点2,权重为3。 节点1连接到节点3,权重为5。 节点2连接到节点4,权重为2。 g[1] {{2, 3}, {3, 5}} g[2] {{1, 3}, {4, 2}} g[3] {{1, 5}} g[4] {{2, 2}} vector<vector<PII>> g;题目背景 有 N…...
2002-2024年地级市新质生产力词频统计数据(46个关键词词频)
2002-2024年地级市新质生产力词频统计数据(46个关键词词频) 1、时间:2002-2024年 2、来源:ZF工作报告 3、指标:行政区划代码、年份、地区、所属省份、文本总长度、仅中英文-文本总长度、文本总词频-全模式、文本总词…...
院校机试刷题第二天:1479 01字符串、1701非素数个数
一、1479 01字符串 1.题目描述 2.解题思路 方法一:暴力法 模拟过程,列出几个数据来a[1]1, a[2]2, a[3]3, a[4]5以此类推,这就是斐波那契数列,每一项都等于前两项之和,确定好a[1], a[2]即可。 方法二:动…...
2011-2019年各省总抚养比数据
2011-2019年各省总抚养比数据 1、时间:2011-2019年 2、来源:国家统计局 3、指标:行政区划代码、地区、年份、总抚养比(人口抽样调查)(%) 4、范围:31省 5、指标解释:总抚养比也称总负担系数。指人口总体中非劳动年…...
3337|3335. 字符串转换后的长度 I(||)
1.字符串转换后的长度 I 1.1题目 3335. 字符串转换后的长度 I - 力扣(LeetCode) 1.2解析 递推法解析 思路框架 我们可以通过定义状态变量来追踪每次转换后各字符的数量变化。具体地,定义状态函数 f(i,c) 表示经过 i 次转换后࿰…...
【电路笔记 通信】8B/10B编码 高速数据传输的串行数据编码技术 论文第三部分 The 8B/10B coding map
0810逻辑总览 The 8B/10B coding map 图 1 展示了一个通信适配器接口,它由八条数据线 A、B、C、D、E、F、G、H(注意:使用大写字母表示)、一条控制线 K,以及一条以字节速率运行的时钟线 BYTECLK 组成。控制线 K 用于指…...
智能化双语LaTeX系统,分阶段系统性开发技术实现路径:目标是实现语义级编译和认知增强写作,推动跨文明知识表达
智能化双语LaTeX系统,分阶段系统性开发技术实现路径(D认为W可辅助各环节开发): 第一阶段:双语LaTeX引擎升级 1. 核心架构设计 Unicode深度支持 开发新一代XeLaTeX/LuaLaTeX内核 原生支持UTF-8编码(如汉…...
【RabbitMQ】路由模式和通配符模式的具体实现
文章目录 路由模式创建队列和交换机生产者代码创建交换机声明队列绑定交换机和队列发送消息完整代码 消费者代码运行程序启动生产者启动消费者 通配符模式创建队列和交换机生产者代码创建交换机声明队列绑定交换机和队列发送消息完整代码 消费者代码运行程序启动生产者启动消费…...
【测试开发知识储备】之Jacoco(Java Code Coverage)
文章目录 Jacoco是什么Jacoco的主要功能(一)多样化覆盖率指标分析(二) 丰富的报告生成(三)实时数据收集 Jacoco的工作原理(一)字节码增强(二)测试执行与数据收…...
大二java第一面小厂(挂)
第一场: mybatis怎么防止数据转义。 Hutool用的那些你常用的方法。 springboot的常用注解。 redis的多级缓存。 websocket怎么实现的多人协作编辑功能。 怎么实现的分库分表。 mysql里面的各种操作,比如说分表怎么分,分页查询怎么用。 mybat…...
Postman接口测试
现在企业级测试分为三层测试 UI层:即与用户交互的层面 Service层:比如前后端分离的系统,测试数据的传输 Unit层:单元测试 接口 接口的概念很抽象,比如我们经常使用的USB接口,Lighting接口等传输电量数据…...
试除法判断素数优化【C语言】
代码引用 int is_prime(int num) {if (num < 1) return 0;if (num 2 || num 3) return 1;if (num % 2 0 || num % 3 0) return 0;for (int i 5; i * i < num; i 6) {if (num % i 0 || num % (i 2) 0) return 0;}return 1; } 一、数学原理 所有大于3的素数都可…...
全新开发-iVX图形化编程VS完整IDE
本文针对传统软件开发的效率与可控性矛盾,系统阐释 iVX"图形化编程 全栈 IDE" 的复合架构如何突破行业瓶颈。通过 "可视化建模 - 标准代码生成 - 独立运行" 的技术闭环,iVX 实现开发效率提升 60% 与源码完全可控的双重目标。研究揭…...
前端表格滑动滚动条太费事,做个浮动滑动插件
比如下面的表格,因为滚动条样式设计得很窄,所以用鼠标滑动起来很费劲 <template><el-table:data"tableData"style"width: 600px"height"250"><el-table-columnfixedprop"date"label"日期&…...
基于自校准分数的扩散模型在并行磁共振成像中联合进行线圈灵敏度校正和运动校正|文献速递-深度学习医疗AI最新文献
Title 题目 Joint coil sensitivity and motion correction in parallel MRI with aself-calibrating score-based diffusion model 基于自校准分数的扩散模型在并行磁共振成像中联合进行线圈灵敏度校正和运动校正 01 文献速递介绍 磁共振成像(MRI)…...
【CUDA】Sgemm单精度矩阵乘法(上)
目录 前言1. 简述2. 框架搭建和CPU串行实现3. baseline算法:global memory4. 优化技巧1:shared memory5. 优化技巧2:shared memory sliding window6. 优化技巧3:增加每个线程的工作量7. 优化技巧4:使用float4提高读取…...
Linux proc文件系统 内存影射
文章目录 常见的内存分配函数/proc/pid/ 目录解析 用户进程的内存空间分配算法mmap 分配大内存可能不在堆中换为 malloc 现象相同 常见的内存分配函数 malloc / calloc / realloc(来自 C 标准库) void *malloc(size_t size):分配 size 字节…...
服务器时间发生跳变导致hghac中对应主机状态频繁切换为crash或stop
文章目录 环境症状问题原因解决方案相关文档报错编码 环境 系统平台:N/A 版本:N/A 症状 集群状态: [rootbthbj-hgywsjkjq-ip28-cen76 ~]# hghactl list Cluster: highgo-ee-cluster —---------------------—---------- | Member | Ho…...
“智”造升级:金众诚如何赋能重型机械企业高效项目管理?
据悉,由中国重型机械工业协会主办的2025中国(郑州)重型机械装备展览会(以下简称:重型机械装备展),将于2025年10月15-17日在河南省郑州市中原国际会展中心隆重举办。 作为中国重型机械行业唯一的…...
反向操作:如何用AI检测工具优化自己的论文“人味”?
大家好,这里是论文写手的一线自救指南😤 在AIGC横行的今天,谁还没偷偷用过AI写几段论文内容?但问题来了:学校越来越会“识AI”了! 有的学校甚至不看重复率,只盯AIGC率报告,一句“AI…...
前端面试宝典---js垃圾回收机制
什么是垃圾回收 垃圾回收是指一种自动内存管理机制,当声明一个变量时,会在内存中开辟一块内存空间用于存放这个变量。当这个变量被使用过后,可能再也不需要它了,此时垃圾回收器会自动检测并回收这些不再使用的内存空间。垃圾回收…...
【docker】--容器管理
文章目录 容器重启--restart 参数选项及作用**对比 always 和 unless-stopped****如何查看容器的重启策略?** 容器重启 –restart 参数选项及作用 重启策略 no:不重启(默认)。on-failure:失败时重启(可限…...
如何下载和安装 Ghost Spectre Windows 11 24H2 PRO
如何下载和安装 Ghost Spectre Windows 11 24H2 PRO 我们都希望拥有一台运行速度飞快的电脑系统,但对于那些使用普通硬件的用户来说,这并不总是可能的。所以,如果你觉得你的 Windows 11 电脑运行缓慢,你并不孤单。许多用户,包括 Reddit 和 YouTube 上的技术爱好者,都在放…...
软考软件设计师中级——软件工程笔记
1.软件过程 1.1能力成熟度模型(CMM) 软件能力成熟度模型(CMM)将软件过程改进分为以下五个成熟度级别,每个级别都定义了特定的过程特征和目标: 初始级 (Initial): 软件开发过程杂乱无章…...
有关多线程
一、多线程到底是什么?简单说一说 你可以把程序想象成一台工厂。单线程就是工厂里只有一个员工,他做事情、搬产品、打包都靠一个人,他忙起来速度会慢一些。而多线程就像有多个员工同时工作,他们各自干自己的事情,整体…...
静电的起因与静电效应:技术分析与应用
杭州干扰净电子科技有限公司出品: 静电(Electrostatics)是由于电荷积累或转移引起的现象,广泛存在于日常生活和工业环境中。静电的起因主要包括接触起电、摩擦起电和感应起电,而其效应可能引发静电放电(ES…...
Python知识框架
一、Python基础语法 变量与数据类型 变量命名规则 基本类型:int, float, str, bool, None 复合类型:list, tuple, dict, set 类型转换与检查(type(), isinstance()) 运算符 算术运算符:, -, *, /, //, %, ** 比较…...
npm install 报错
1、protobufjs7.4.0 postinstall: node scripts/postinstall verbose stack Error: protobufjs7.4.0 postinstall: node scripts/postinstall 确认是否有postinstall# node scripts/postinstallCannot find module /home/rio/scripts/postinstall解决办法: # 添加…...
ESP32WIFI工具加透传
工欲善其事,必先利器其器 项目首页 - ESP-12F烧录使用软件与说明书:ESP-12F 烧录使用软件与说明书本仓库提供了ESP-12F模块的烧录使用软件及相关说明书,帮助用户快速上手并使用ESP-12F模块进行开发 - GitCode ATCWMODE 是 ESP32 系列芯片中用于设置 Wi…...
44、私有程序集与共享程序集有什么区别?
私有程序集(Private Assembly)与共享程序集(Shared Assembly)是.NET框架中程序集部署的两种不同方式,它们在部署位置、版本控制、访问权限等方面存在显著差异,以下是对二者的详细比较: 1. 部署…...
Hadoop集群故障节点隔离操作指南
一、确认故障节点状态 1.查看集群节点状态 hdfs dfsadmin -report # 显示所有DataNode状态(存活/宕机/存储利用率) 输出中标记为 Dead 或 Decommissioning 的节点为异常节点。 2.分析监控指标 通过Prometheus/Grafana监控平台检查节点资源(CPU、内存、磁盘I…...
流速仪数据处理及流量断面线绘制
1 需求描述 在实际航道测量项目中,有测量断面线流量流速的需求,得使用流速仪在现场进行测量,相关操作在之前已经写了记录。本次手册记录后期数据处理与流量线绘制,以该区域为例。 流速仪设备操作说明 2 规范要求 3 流量断面表格…...
android实现USB通讯
在 Android 上枚举 USB 设备除了使用 UsbManager.getDeviceList() 方法外,还有以下几种常见的方式: 1. 使用 USB 设备过滤器(XML 配置) 通过在 AndroidManifest.xml 中配置 USB 设备过滤器,可以让系统自动检测并通知…...
公链开发及其配套设施:钱包与区块链浏览器
公链开发及其配套设施:钱包与区块链浏览器的技术架构与生态实践 ——2025年区块链基础设施建设的核心逻辑与创新突破 一、公链开发:构建去中心化世界的基石 1. 技术架构设计的三重挑战 公链作为开放的区块链网络,需在性能、安全性与去中心…...
SVM在医疗设备故障维修服务决策中的应用:策略、技术与实践
SVM在医疗设备故障维修服务决策中的应用:策略、技术与实践 医疗设备的高可靠性、安全性及严格合规性要求,使其故障维修决策具有显著的特殊性。支持向量机(SVM)凭借小样本学习、非线性建模及高精度分类能力,可有效解决…...
如何高效集成MySQL数据到金蝶云星空
MySQL数据集成到金蝶云星空:SC采购入库-深圳天一-OK案例分享 在企业信息化建设中,数据的高效流转和准确对接是实现业务流程自动化的关键。本文将聚焦于一个具体的系统对接集成案例——“SC采购入库-深圳天一-OK”,详细探讨如何通过轻易云数据…...
NACOS基于长链接的⼀致性模型
1. 配置⼀致性模型 sdk-server ⼀致性 server 间⼀致性 Server 间同步消息接收处理轻量级实现,重试失败时,监控告警。断网:断网太久,重试任务队列爆满时,无剔除策略。 2. 服务⼀致性模型...
Docker 常见问题及其解决方案
一、安装与启动问题 1.1 安装失败 在不同操作系统上安装 Docker 时,可能会出现安装失败的情况。例如,在 Ubuntu 系统中,执行安装命令后提示依赖缺失。这通常是因为软件源配置不正确或系统缺少必要的依赖包。 解决方案: 确保系统…...
Nginx 动静分离在 ZKmall 开源商城静态资源管理中的深度优化
在 B2C 电商高并发场景下,静态资源(图片、CSS、JavaScript 等)的高效管理直接影响页面加载速度与用户体验。ZKmall开源商城通过对 Nginx 动静分离技术的深度优化,将静态资源响应速度提升 65%,带宽成本降低 40%…...
Lighthouse 自定义审计
以下是关于 Lighthouse 自定义审计的基本知识点总结: 一、Lighthouse 自定义审计核心概念 1. 审计机制架构 #mermaid-svg-lzu9WEel4gUome5N {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-lzu9WEel4gUome5N .erro…...
龙虎榜——20250514
上证日线收阳线,大盘股相对强势,整体跌多涨少,量能较昨日放大,大金融发力,但总体处于日线上涨末端,注意风险。 深证日线冲高回落,触及前期压力位,量能未放大,总体处于日…...
基于javaweb的SpringBoot自习室预约系统设计与实现(源码+文档+部署讲解)
技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...
二分查找的边界问题
前言 二分查找(Binary Search)是一种高效的查找算法,时间复杂度为O(log n)。它适用于已排序的数组或列表。本文将详细介绍二分查找的两种常见写法:闭区间写法和左闭右开区间写法。 一、二分查找基本思想 二分查找的核心思想是"分而治之"&am…...
应用示例1:交通灯
基于FPGA的交通灯控制系统实现原理详解 目录 基于FPGA的交通灯控制系统实现原理详解一、项目简介二、数字电路与基础知识1. 交通灯系统的有限状态机(FSM)2. 数码管显示原理3. 二进制转BCD显示4. 时钟与分频三、功能需求与系统结构功能需求系统结构四、各模块设计原理说明1. 时…...