JAVA Internet Architect Thematic/distributed/high concurrency/micro service
Dianme: JAVA Internet Architect Thematic/Distributed/High Concurrency/Microservice Extraction Horse: XB2K
- Start the Seata Server
1) Specify nacOS as the configuration center and registry to modify the registry. Conf file V (cmL46679910)
Note: When configuring registry. Conf to use nacos, also note that the group is the same as the group in seata Server. The default group is “DEFAULT_GROUP”.
2) Synchronize seATA Server configuration to NACOS
Obtain /seata/script/config-center/config. TXT and modify the configuration information
Configuration affairs group, in accordance with client configuration affairs group (client configuration properties: spring. Cloud. Alibaba. Seata. Tx ‐ servicegroup = my_test_tx_group)
Configuration parameters are synchronized to Nacos
shell: Sh ${SEATAPATH}/script/config‐center/nacos/nacos‐config.sh ‐h localhost ‐p 8848 ‐g SEATA_GROUP ‐t 5a3C7d6c ‐f497‐4d68‐ a71A ‐ 2e5e3340B3CA Parameter description: -h: host, default value localhost AC V (cmL46679910) -p: port, default value 8848 -g: To configure groups, the default value is ‘SEATA_GROUP’ -t: tenant information, corresponding to the NAMESPACE ID field of Nacos. The default value is empty.
3) Start the Seata Server
Run the bin/ Seata ‐server.sh command to start the Seata Server. The default port is 8091
In the registry, you can see that seata-Server has been registered successfully
- How does Seata integrate into Spring Cloud microservices
Service Scenario:
The entire business logic is composed of three micro-services: Warehousing service: deducting the amount of inventory for a given item. Order service: Create orders based on purchase requirements. Account service: Deduct the balance from the user’s account. Dianme: JAVA Internet Architect Thematic/Distributed/High Concurrency/Microservice Extraction Horse: XB2K
Environment preparation: SEATA: V1.4.0 Spring Cloud&Spring Cloud Alibaba: 1 < spring ‐ cloud. Version > Greenwich. The SR3 < / spring ‐ cloud. Version > 2 <spring‐cloud‐alibaba.version>2.1.1.RELEASE</spring‐cloud‐alibaba.version> When Using Seata1.4.0 for Spring Cloud Alibaba 2.1.2 and later (supports SEATA 1.3.0)
2.1 Importing Dependencies
< the dependency > < groupId > com. Alibaba. Cloud < / groupId > < artifactId > spring ‐ cloud ‐ starter ‐ alibaba ‐ seata < / artifactId > < Exclusions > < Exclusion > <groupId> IO. Seata </groupId> <artifactId>seata‐all</artifactId> </ Exclusion > </ Exclusions > </artifactId> seata‐all</artifactId> </artifactId> The < version > 1.4.0 < / version > < / dependency > <! ‐‐ dependency> <groupId>com.alibaba.cloud</groupId> < artifactId > spring ‐ cloud ‐ starter ‐ alibaba ‐ nacos ‐ discovery < / artifactId > < / dependency > < the dependency > < the groupId > org. Springframework. Cloud < / groupId > < artifactId > spring ‐ cloud ‐ starter ‐ openfeign < / artifactId > < / dependency > < the dependency > < groupId > com. Alibaba < / groupId > < artifactId > druid ‐ spring ‐ boot ‐ starter < / artifactId > < version > 1.1.21 < / version > < / dependency > < the dependency > < groupId > mysql < / groupId > < artifactId > mysql ‐ connector ‐ Java < / artifactId > </groupId> </groupId> </groupId> </groupId> </groupId> </groupId> < artifactId > mybatis ‐ spring ‐ boot ‐ starter < / artifactId > < version > 2.1.1 < / version > < / dependency >Copy the code
2.2 Add the undo_log table to the database corresponding to the micro service
“`CREATE TABLE undo_log ( id bigint(20) NOT NULL AUTO_INCREMENT, branch_id bigint(20) NOT NULL, xid varchar(100) NOT NULL, context varchar(128) NOT NULL, rollback_info longblob NOT NULL, Log_status int(11) NOT NULL, ac V (cmL46679910) log_created datetime NOT NULL, LOG_modified datetime NOT NULL PRIMARY KEY (id), UNIQUE KEY ux_undo_log (xid,branch_id) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
2.3 The microservice needs to use SeATA DataSourceProxy to proxy its own data sourceCopy the code
/ * *
- @author Fox
- Microservices that need to use distributed transactions need to use SeATA DataSourceProxy to proxy their data sources
*/ @Configuration @MapperScan(“com.tuling.datasource.mapper”) public class MybatisConfig {
/ * *
- Build a datasource with attributes from the configuration file. Note the prefix druid.
- Native datasource prefixes “spring. Datasource”
- @return
/ @Bean @ConfigurationProperties(prefix = “spring.datasource”) public DataSource druidDataSource() { DruidDataSource druidDataSource = new DruidDataSource(); return druidDataSource; } ac V (cmL46679910) /*
- Construct a datasource proxy object that replaces the original datasource
- @param druidDataSource
- @return
*/ @Primary @Bean(“dataSource”) public DataSourceProxy dataSourceProxy(DataSource druidDataSource) { return new DataSourceProxy(druidDataSource); }
@Bean(name = “sqlSessionFactory”) public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourcePro xy) throws Exception { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); / / set the proxy data source factoryBean. SetDataSource (dataSourceProxy); ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); FactoryBean. SetMapperLocations (resolver. GetResources (” classpath * : mybatis / * * / * ‐ mapper. The XML “));
org.apache.ibatis.session.Configuration configuration=new org.apache.ibatis.session.Configuration(); / / using the JDBC getGeneratedKeys access database on the primary key value configuration. SetUseGeneratedKeys (true); / / use column alias substitution column configuration. SetUseColumnLabel (true); / / automatically using hump naming attribute mapping fields, such as userId ‐ ‐ ‐ > user_id configuration. SetMapUnderscoreToCamelCase (true); factoryBean.setConfiguration(configuration);
return factoryBean.getObject(); }
} note: start the class need to exclude DataSourceAutoConfiguration, otherwise there will be a circular dependencies
Start the class rule out DataSourceAutoConfiguration. Class
@SpringBootApplication(scanBasePackages = “com.tuling”,exclude = DataSourceAut oConfiguration.class) public class AccountServiceApplication {communication V (cmL46679910)
public static void main(String[] args) { SpringApplication.run(AccountServiceApplication.class, args); }
}
Copy the registry. Conf file to the resources directory. Nacos registry {# file, nacos, Eureka, redis, zk, consul, etcd3, sofa type = "nacos" nacos {serverAddr = "192.168.65.232:8848" namespace = "" cluster = "default" group = "SEATA_GROUP"}} config {# file, nacos V** (**cmL46679910**) {nacos {serverAddr = Namespace = "29ccF18e ‐e559‐4a01‐b5d4‐ 61bad4a89FFd" group = "SEATA_GROUP"}}Copy the code
In the org. Springframework. Cloud: spring — cloud – starter – alibaba – seata Org. Springframework. Cloud. Alibaba. Seata. GlobalTransactionAutoConfiguration class, The default will use ${spring. Application. The name} – seata – service – group as a service note Copies to Seata Server, if and service vgroup_mapping configuration, No available server will be prompted to connect error Can also be configured spring. Cloud. Alibaba. Seata. Tx – service – group modified suffix, but must and file the conf is consistent with the configuration
2) Specify transaction groups in YML (corresponding to configuration center’s service.vgroup_mapping configuration)
Application: Name: Account ‐service Cloud: nacos: Discovery: server‐addr: 127.0.0.1:8848 Tx ‐service‐group: my_test_tx_groupCopy the code
Reference source: Io.seata.core.rpc.netty.Net tyClientChannelManager# getAvailServerList NacosRegistryServiceImpl# “lookup” String clusterName = getServiceGroup(key); List firstAllInstances = getNamingInstance().getallInstances (getServiceName(), getServiceGroup(), getServiceName(), getServiceGroup(), clusters)
After Spring Cloud Alibaba 2.1.4, seata properties can be configured in YML, which can be used to replace the registry
1 2 IO. Seata 3 seata‐spring‐boot‐starter 4 1.4.0 5
Configure in YML
Tx ‐service‐group: my_test_tx_group registry: my_test_tx_group registry: Nacos: server‐addr: 127.0.0.1:8848 Namespace: "" group: SEATA_GROUP config: Nacos: server‐addr: 127.0.0.1:8848 Namespace: "54433b62‐ DF64 ‐ 40F1 ‐9527‐c907219fc17f" group: SEATA_GROUPCopy the code
3) Add the @GlobalTransactional annotation core code to the transaction initiator
//@Transactional @GlobalTransactional(name="createOrder") public Order saveOrder(OrderVo orderVo){ Log.info ("============= user order ================="); Log.info (" current XID: {}", rootContext.getxid ()); Order Order = new Order(); order.setUserId(orderVo.getUserId()); order.setCommodityCode(orderVo.getCommodityCode()); order.setCount(orderVo.getCount()); order.setMoney(orderVo.getMoney()); CmL46679910 communication V * * * * (* * * *) order. The setStatus (OrderStatus. INIT. GetValue ()); V** (**cmL46679910**) Integer saveOrderRecord = orderMapper.insert(order); The log. The info (" save order {} ", ac V * * * * (* * cmL46679910 * *) saveOrderRecord > 0? "success" : "failure"); / / deduct inventory storageFeignService. Deduct (orderVo getCommodityCode (), orderVo. GetCount ()); / / deductions balance accountFeignService. Debit (orderVo getUserId (), orderVo. GetMoney ()); / / update order Integer updateOrderRecord = orderMapper. UpdateOrderStatus (order. The getId (), Orde rStatus. SUCCESS. The getValue ()); Log.info (" update order ID :{} {}", order.getid (), updateOrderRecord > 0? "success" : "failed "); return order; }Copy the code