分布式事务-LCN

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 分布式事务-LCN

正文


一、什么是事务


事务:是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元


事务的四大特性:ACID


Atomicity(原子性):一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。


Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。  


Isolation(隔离性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。

Durability(持久性):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。


分布式事务产生的原因


随着互联网的迅速发展,单体项目已经不能满足日益复杂的业务需求。后来逐渐演变出分布式。既然有分布式项目,就相应的会产生分布式事务。分布式系统会把一个应用系统拆分为可独立部署的多个服务,因此需要服务与服务之间远程协作才能完成事务操作,这种分布式系统环境下由不同的服务之间通过网络远程协作完成事务称之为分布式事务。比如订单系统,订单完成之后,需要调用会员系统给用户积分,此时,若积分业务成功,然后订单系统突然发生异常,此时就会涉及到分布式事务。


二、CAP&BASE理论


CAP理论

CAP定律


   这个定理的内容是指的是在一个分布式系统中、Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。


一致性(C)


   在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)


可用性(A)


   在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)


分区容错性(P)


   以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。


BASE理论


BASE是Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent(最终一致性)三个短语的缩写。BASE理论是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的总结, 是基于CAP定理逐步演化而来的。BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。


基本可用


   基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性—-注意,这绝不等价于系统不可用。比如:


(1)响应时间上的损失。正常情况下,一个在线搜索引擎需要在0.5秒之内返回给用户相应的查询结果,但由于出现故障,查询结果的响应时间增加了1~2秒


(2)系统功能上的损失:正常情况下,在一个电子商务网站上进行购物的时候,消费者几乎能够顺利完成每一笔订单,但是在一些节日大促购物高峰的时候,由于消费者的购物行为激增,为了保护购物系统的稳定性,部分消费者可能会被引导到一个降级页面


软状态


   软状态指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时


最终一致性


   最终一致性强调的是所有的数据副本,在经过一段时间的同步之后,最终都能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。


三、核心步骤


创建事务组


是指在事务发起方开始执行业务代码之前先调用TxManager创建事务组对象,然后拿到事务标示GroupId的过程。


加入事务组


添加事务组是指参与方在执行完业务方法以后,将该模块的事务信息通知给TxManager的操作。


通知事务组


是指在发起方执行完业务代码以后,将发起方执行结果状态通知给TxManager,TxManager将根据事务最终状态和事务组的信息来通知相应的参与模块提交或回滚事务,并返回结果给事务发起方。


摘自  https://www.codingapi.com/docs/txlcn-preface/


四、代码


事务协调者

下载源码 https://github.com/codingapi/tx-lcn/releases/tag/5.0.2.RELEASE


源码里有sql语句,创建数据库tx-managr,然后创建表


修改txlcn-tm配置文件


spring.application.name=TransactionManager
server.port=7970
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tx-manager?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=update
#redis
spring.redis.host=192.168.6.130
spring.redis.port=6379
spring.redis.password=xiaojie
spring.redis.timeout=5000
#配置日志
tx-lcn.logger.enabled=true
tx.log
#后台登录的密码
tx-lcn.manager.admin-key=123456


登录后台地址:http://127.0.0.1:7970/admin/index.html#/ 密码为123456


事务发起方代码如下


配置文件


spring:
  application:
    name: xiaojie-order
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      discovery:
        enabled: true
  datasource:
    url: jdbc:mysql://localhost:3306/order?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
server:
  port: 8090
tx-lcn:
  client:
    manager-address: 127.0.0.1:8070
  logger:
    enabled: true


Mapper接口


package com.xiaojie.lcn.api.order.impl.mapper;
import org.apache.ibatis.annotations.Update;
/**
 * @Description:
 * @author: xiaojie
 * @date: 2021.07.19
 */
public interface OrderMapper {
    @Update("update tb_order set orderState=1 where orderId=#{orderId}")
    Integer finishOrder(String orderId);
}


OpenFeign


package com.xiaojie.lcn.api.order.impl.service.feign;
import com.xiaojie.api.member.service.ScoreService;
import org.springframework.cloud.openfeign.FeignClient;
/**
 * @Description:
 * @author: xiaojie
 * @date: 2021.07.19
 */
@FeignClient("xiaojie-member")
public interface ScoreServiceFeign extends ScoreService {
}


接口api


package com.xiaojie.lcn.api.member.impl.service;
import com.codingapi.txlcn.tc.annotation.LcnTransaction;
import com.xiaojie.api.member.entity.Score;
import com.xiaojie.api.member.service.ScoreService;
import com.xiaojie.lcn.api.member.impl.mapper.ScoreMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController;
/**
 * @Description: 积分服务
 * @author: xiaojie
 * @date: 2021.07.19
 */
@RestController
public class ScoreServiceImpl  implements ScoreService {
    @Autowired
    private ScoreMapper scoreMapper;
    @Override
    @Transactional
    @LcnTransaction
    public Integer saveScore(Score score) {
        return scoreMapper.save(score);
    }
}


启动类


package com.xiaojie.lcn.api.member.impl;
import com.codingapi.txlcn.tc.config.EnableDistributedTransaction;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
 * @Description:
 * @author: xiaojie
 * @date: 2021.07.19
 */
@SpringBootApplication
@EnableDistributedTransaction
@EnableFeignClients
@MapperScan("com.xiaojie.lcn.api.member.impl.mapper")
public class MemberApp {
    public static void main(String[] args) {
        SpringApplication.run(MemberApp.class);
    }
}


完整实例请参考https://github.com/xiaojiewhisper/xiaojie-lcn.git


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
7月前
|
存储 关系型数据库 Java
技术经验解读:三种分布式事务LCN、Seata、MQ
技术经验解读:三种分布式事务LCN、Seata、MQ
233 0
|
算法 Dubbo Java
基于SpringBoot的分布式事务LCN整合分享
基于SpringBoot的分布式事务LCN整合分享
102 0
|
负载均衡 NoSQL Dubbo
【SpringCloud系列】 分布式事务-LCN
一、什么是分布式事务 分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。 二,TX-LEN TX-LCN分布式事务框架,LCN并不生产事务,LCN只是本地事务的协调工,LCN是一个高性能的分布式事务框架,兼容dubbo、springcloud框架,支持RPC框架拓展,支持各种ORM框架、NoSQL、负载均衡、事务补偿 特性:   1、一致性,通过TxManager协调控制与事务补偿机制确保数据一致性   2、易用性,仅需要在业务方
311 0
【SpringCloud系列】 分布式事务-LCN
|
Java 应用服务中间件 数据库
分布式事务解决方案框架(LCN)
事物概念 事物特性(ACID) 原子性(A) 所谓的原子性就是说,在整个事务中的所有操作,要么全部完成,要么全部不做,没有中间状态。对于事务在执行中发生错误,所有的操作都会被回滚,整个事务就像从没被执行过一样。
3162 0
|
3月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
5月前
|
NoSQL Redis
基于Redis的高可用分布式锁——RedLock
这篇文章介绍了基于Redis的高可用分布式锁RedLock的概念、工作流程、获取和释放锁的方法,以及RedLock相比单机锁在高可用性上的优势,同时指出了其在某些特殊场景下的不足,并提到了ZooKeeper作为另一种实现分布式锁的方案。
136 2
基于Redis的高可用分布式锁——RedLock
|
30天前
|
存储 NoSQL Java
使用lock4j-redis-template-spring-boot-starter实现redis分布式锁
通过使用 `lock4j-redis-template-spring-boot-starter`,我们可以轻松实现 Redis 分布式锁,从而解决分布式系统中多个实例并发访问共享资源的问题。合理配置和使用分布式锁,可以有效提高系统的稳定性和数据的一致性。希望本文对你在实际项目中使用 Redis 分布式锁有所帮助。
96 5
|
2月前
|
NoSQL Java 数据处理
基于Redis海量数据场景分布式ID架构实践
【11月更文挑战第30天】在现代分布式系统中,生成全局唯一的ID是一个常见且重要的需求。在微服务架构中,各个服务可能需要生成唯一标识符,如用户ID、订单ID等。传统的自增ID已经无法满足在集群环境下保持唯一性的要求,而分布式ID解决方案能够确保即使在多个实例间也能生成全局唯一的标识符。本文将深入探讨如何利用Redis实现分布式ID生成,并通过Java语言展示多个示例,同时分析每个实践方案的优缺点。
70 8
|
2月前
|
NoSQL Redis
Redis分布式锁如何实现 ?
Redis分布式锁通过SETNX指令实现,确保仅在键不存在时设置值。此机制用于控制多个线程对共享资源的访问,避免并发冲突。然而,实际应用中需解决死锁、锁超时、归一化、可重入及阻塞等问题,以确保系统的稳定性和可靠性。解决方案包括设置锁超时、引入Watch Dog机制、使用ThreadLocal绑定加解锁操作、实现计数器支持可重入锁以及采用自旋锁思想处理阻塞请求。
61 16
|
2月前
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
44 5