1. Спрос
Служба вычета запасов и служба формирования заказов соответствуют разным базам данных, локальная транзакция Spring @Transactional не может решить проблему обеспечения согласованности данных между базами данных и службами. Распределенные транзакции обычно включают в себя инициаторов и участников транзакций, службы ресурсов реляционных баз данных и менеджеры транзакций.Среда распределенных транзакций в основном популярна для TX-LCN и среды Seata от Ali.В следующей статье будет рассмотрена среда Seata.
Платформа распределенных транзакций TX-LCN — это платформа распределенных транзакций с открытым исходным кодом. Она состоит из двух модулей: TxClient и TxManager. TxClient играет роль инициатора и участника, а TxManager играет роль диспетчера транзакций для координации транзакций. С точки зрения разработки , TxClient относится к Это наша собственная система обслуживания, а TxManager — это система координации центра транзакций; из версии Github RELEASE последняя версия — 5.0.2.RELEASE (поддерживает три режима транзакций LCN TXC TCC), проект использует v4.1.0 для стабильности (по умолчанию поддерживается только режим LCN); основной принцип режима LCN заключается в том, что прокси-аспект перехватывает фиксацию и откат всех ссылок на базу данных, а объект прокси-соединения контролирует реальную фиксацию, откат и выпуск локальной транзакции. При наличии нереляционной базы данных redis требуется операция компенсации в режиме TCC, чтобы обеспечить общую согласованность нереляционной redis и реляционной mysql.
2. Начать подготовку
1. Подготовьте среды mysql и redis с помощьюspring initializrБыстро подготовьте реестр Eureka.
2. Скачатьv4.1.0Версия tx-lcn-4.1.0 — это проект весенней загрузки, для которого требуется служба реестра eureka и Redis, а также выполняется класс запуска com.codingapi.tm.TxManagerApplication.
3. Доступhttp://127.0.0.1:8899/В интерфейсе управления TxManager обратите внимание на порт двух свойств адрес сервера балансировки нагрузки и текущее количество подключений.Это скриншот успешного эксперимента.Текущее количество подключений должно быть 0 в начале.
4.Пример демо распределенной транзакции Springcloud LCN v4.0
Создайте соответствующую базу данных и измените конфигурацию в соответствии с учебным руководством, сосредоточив внимание на важной конфигурации. Мы ориентируемся на jdbc-версию springcloud-jdbc-demo, которая включает в себя бизнес-модули 5. Проекты соответствуют портам с 1 по 5: с 8081 по 8085. Префикс интерфейса контроллера — localhost:port/demo, а список интерфейсы и интерфейс сохранения; в методе сохранения demo3 (вызов 4 и 5, self) и demo1 (вызов 2 и 3, self) являются инициаторами транзакции. Разница между ними заключается в том, что demo3 аннотирует исключение и возвращает 3 части данных вставки обычно, в то время как открытое исключение demo1 запускает распределенную транзакцию для отката вставленных данных; demo2, demo4 и demo5 являются только участниками транзакции.
feign.hystrix.enabled=false
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.url= jdbc:mysql://localhost:3306/test
spring.datasource.username= root
spring.datasource.password=root
spring.datasource.initialize = true
init-db= true
spring.application.name = demo3
server.port = 8083
#${random.int[9000,9999]},注册中心端口要对应
eureka.client.service-url.defaultZone=http://127.0.0.1:8761/eureka/
feign.hystrix.enabled=true
# 关于**springcloud-hystrix机制,选择信号量隔离** http://www.jianshu.com/p/b8d21248c9b1
hystrix.command.default.execution.isolation.strategy= SEMAPHORE
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
#Ribbon的负载均衡策略,重试次数为0
ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
ribbon.MaxAutoRetriesNextServer=0
#**txmanager地址端口指的是TxManager管理界面的负载均衡服务器地址的端口**
tm.manager.url=http://127.0.0.1:8899/tx/manager/
logging.level.com.codingapi=debug
В качестве примера возьмем распределение запуска исключений DemoServiceImpl в demo1, основное внимание уделяется @TxTransaction(isStart = true) отметить инициатора транзакции, иначе у ThreadLocal не будет groupid, тогда не будет группы транзакций, а откатить транзакцию тем более невозможно.
Если на непомеченном инициаторе есть исключение, groupId будет пустым:
2020-05-30 17:30:06.387 DEBUG 4964 --- [nio-8084-exec-8] c.c.t.s.interceptor.TransactionAspect : annotation-TransactionRunning-start---->
2020-05-30 17:30:06.387 DEBUG 4964 --- [nio-8084-exec-8] c.c.t.a.s.impl.AspectBeforeServiceImpl : around--> groupId-> null,txTransactionLocal->null
2020-05-30 17:30:06.387 DEBUG 4964 --- [nio-8084-exec-8] c.c.t.d.aspect.DataSourceAspect : getConnection-start---->
2020-05-30 17:30:06.387 DEBUG 4964 --- [nio-8084-exec-8] c.c.tx.datasource.AbstractResourceProxy : loadConnection -> null !
DemoServiceImpl
package com.example.demo.service.impl;
import com.example.demo.client.Demo2Client;
import com.example.demo.client.Demo3Client;
import com.example.demo.dao.TestDao;
import com.example.demo.entity.Test;
import com.example.demo.service.DemoService;
import com.codingapi.tx.annotation.TxTransaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* Created by lorne on 2017/6/26.
*/
@Service
public class DemoServiceImpl implements DemoService {
@Autowired
private TestDao testDao;
@Autowired
private Demo2Client demo2Client;
@Autowired
private Demo3Client demo3Client;
@Override
public List<Test> list() {
return testDao.list();
}
@Override
**@TxTransaction(isStart = true)**
@Transactional
public int save() {
int rs2 = demo2Client.save();
int rs3 = demo3Client.save();
int rs1 = testDao.save();
int v = 100/0;
return rs1+rs2+rs3;
}
}
Доступ к интерфейсу сохранения demo1
//访问save接口:http://localhost:8081/demo/save,触发异常
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sat May 30 17:33:11 CST 2020
There was an unexpected error (type=Internal Server Error, status=500).
Demo3Client#save() failed and fallback failed.
Запустите откат консоли JdbcDemo2Application с правильным журналом:
#触发回滚
2020-05-30 17:33:11.654 DEBUG 4468 --- [ntLoopGroup-2-1] c.c.tx.netty.handler.TransactionHandler : TxManager-response->{"a":"t","c":0,"t":"9Fxhh19M","k":"62kQVGPh"}
2020-05-30 17:33:11.654 INFO 4468 --- [ool-1-thread-19] c.c.t.c.service.impl.ActionTServiceImpl : accept notify data ->{"a":"t","c":0,"t":"9Fxhh19M","k":"62kQVGPh"}
lcn transaction over, res -> groupId:3OBwlhvN and state is rollback
2020-05-30 17:33:11.657 DEBUG 4468 --- [ Thread-28] c.c.t.d.relational.LCNDBConnection : lcnConnection closed groupId:3OBwlhvN
2020-05-30 17:33:11.658 INFO 4468 --- [ool-1-thread-19] c.c.t.c.service.impl.ActionTServiceImpl : accept notify response res ->1
2020-05-30 17:33:11.658 DEBUG 4468 --- [ool-1-thread-19] .c.t.c.s.i.TransactionControlServiceImpl : send notify data ->{"p":{"d":"1"},"a":"t","k":"62kQVGPh"}
2020-05-30 17:33:11.659 DEBUG 4468 --- [ntLoopGroup-2-1] c.c.tx.netty.handler.TransactionHandler : TxManager-response->{"d":"","k":"62kQVGPh"}
#clent和manager的心跳数据
2020-05-30 17:33:26.659 DEBUG 4468 --- [ntLoopGroup-2-1] c.c.tx.netty.handler.TransactionHandler : hart data --->{"p":"{}","a":"h","k":"h"}
2020-05-30 17:33:26.659 DEBUG 4468 --- [ntLoopGroup-2-1] c.c.tx.netty.handler.TransactionHandler : TxManager-response->{"d":"5","k":"h"}
3. Различия между версиями 4.0 и 5.0
Версия 5.0 была отправлена в большом количестве с января и была разработана и поддерживается командой codingApi Исходный код аннотаций двух версий отличается.
/** **4.0版本**
* Created by lorne on 2017/6/26.
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface TxTransaction {
/**
* 是否LCN事务发起方
* @return true 是:是发起方 false 否:是参与方
*/
boolean isStart() default false;
/**
* 回滚异常
* @return
*/
Class<? extends Throwable>[] rollbackFor() default {};
/**
* 不回滚异常
* @return
*/
Class<? extends Throwable>[] noRollbackFor() default {};
}
/****5.0版本**
* Created by lorne on 2017/6/26.
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface TxTransaction {
/**
* 事务模式 transaction type
*
* @return lcn, tcc, txc
* @see Transactions
*/
String type() default Transactions.LCN;
/**
* 分布式事务传播行为
*
* @return 传播行为
* @see DTXPropagation
*/
DTXPropagation propagation() default DTXPropagation.REQUIRED;
}