[SpringCloudAlibaba] Uso de transacciones distribuidas de Seata

Ejemplo de problema de transacción distribuida

La aplicación única se divide en aplicaciones de microservicio. Los tres módulos originales se dividen en tres aplicaciones independientes, cada una de las cuales utiliza tres fuentes de datos independientes. Las
operaciones comerciales deben llamar a tres servicios para completarse. En este momento, la coherencia de los datos dentro de cada servicio está garantizada mediante transacciones locales, pero no se puede garantizar el problema de coherencia de los datos globales.
Insertar descripción de la imagen aquí

Descripción general de Seata, sitio web oficial

Sitio web oficial
http://seata.io/zh-cn/Descargar
https://github.com/seata/seata/releases

Un proceso de transacción distribuido típico

Modelo de un ID + tres componentes del proceso de procesamiento de transacciones distribuidas

  • ID de transacción XID: ID de transacción único a nivel mundial;
  • Coordinador de transacciones (TC): el coordinador de transacciones mantiene el estado de ejecución de las transacciones globales y es responsable de coordinar e impulsar el envío o la reversión de transacciones globales;
  • Transaction Manager™: controla los límites de las transacciones globales, es responsable de iniciar una transacción global y, en última instancia, de iniciar resoluciones de compromiso o reversión global;
  • Administrador de recursos (RM): controla las transacciones de las sucursales, es responsable del registro de las sucursales, los informes de estado, recibe instrucciones del coordinador de transacciones e impulsa el envío y la reversión de las transacciones de las sucursales (locales);

Procesando

  1. TM aplica a TC para abrir una transacción global, la transacción global se crea con éxito y se genera un XID globalmente único;
  2. Los XID se propagan dentro del contexto del enlace de llamada del microservicio;
  3. RM registra la transacción de sucursal con TC y la lleva a la jurisdicción de la transacción global correspondiente a XID;
  4. TM inicia una resolución global de confirmación o reversión de XID a TC;
  5. TC programa todas las transacciones de sucursales regidas por el XID para completar la solicitud de confirmación o reversión.
    Insertar descripción de la imagen aquí

Global @GlobalTransactional

Comparado con las anotaciones de Spring@Transactional

Diagrama de flujo de la solución de comercio distribuido

Insertar descripción de la imagen aquí

Instalación de asiento

descargar

Versión 1.7
https://github.com/seata/seata/releases

Modifique el archivo de configuración application.yml en el directorio conf

  1. Primero haga una copia de seguridad del archivo application.yml original
  2. Modificaciones principales: nombre del grupo de transacciones personalizado + modo de almacenamiento del registro de transacciones es db + información de conexión de la base de datos (para ver un ejemplo, consulte application.example.yml)
  3. Crear tabla sql enscript/server/db

panel

http://localhost:7091/
El puerto predeterminado 7091
cambia a chino
Insertar descripción de la imagen aquí

manifestación

@GlobalTransactional(name = “fsp-create-order”,rollbackFor = Exception.class)
Tome el nombre usted mismo, siempre que sea único, se generará la excepción rollbackFor.

  • Problemas que surgen cuando no se agrega esta anotación: En el ejemplo, la llamada accountService.decrease(order.getUserId(), order.getMoney()); no tiene éxito pero el estado del pedido continuará modificándose y el valor de la cuenta será reducido.
//Service全都使用Feign可设置Time.Sleep来模拟Feign调用不成功
//示例中
//@GlobalTransactional(name = "fsp-create-order",rollbackFor = Exception.class)
public void create(Order order)
{
    
    
    log.info("----->开始新建订单");
    //1 新建订单
    orderDao.create(order);

    //2 扣减库存
    log.info("----->订单微服务开始调用库存,做扣减Count");
    storageService.decrease(order.getProductId(),order.getCount());
    log.info("----->订单微服务开始调用库存,做扣减end");

    //3 扣减账户
    log.info("----->订单微服务开始调用账户,做扣减Money");
    accountService.decrease(order.getUserId(),order.getMoney());
    log.info("----->订单微服务开始调用账户,做扣减end");

    //4 修改订单状态,从零到1,1代表已经完成
    log.info("----->修改订单状态开始");
    orderDao.update(order.getUserId(),0);
    log.info("----->修改订单状态结束");

    log.info("----->下订单结束了,O(∩_∩)O哈哈~");

}
//模拟Feign调用不成功示例,Feign默认超时1秒不成功
public void decrease(Long userId, BigDecimal money) {
    
    
    LOGGER.info("------->account-service中扣减账户余额开始");
    //模拟超时异常,全局事务回滚
    //暂停几秒钟线程
    try {
    
     TimeUnit.SECONDS.sleep(20); } catch (InterruptedException e) {
    
     e.printStackTrace(); }
    accountDao.decrease(userId,money);
    LOGGER.info("------->account-service中扣减账户余额结束");
}

Supongo que te gusta

Origin blog.csdn.net/qq_45742250/article/details/132542082
Recomendado
Clasificación