内容简介:之前我写过一个基于springboot1.5.6+lcn4.1.0 的集成文章
前言
之前我写过一个基于springboot1.5.6+lcn4.1.0 的集成文章 https://segmentfault.com/a/11... ,基于目前更新的lcn5.0.2分析了一波源码。在此做一些记录(ps:如果对分布式事务不是很了解,可以先看下我上面贴的链接,本文基于有基础的情况去分析的)
TX-LCN的3种模式
LCN5.0.2有3种模式,分别是LCN模式,TCC模式,TXC模式
-
LCN模式:
LCN模式是通过代理Connection的方式实现对本地事务的操作,然后在由TxManager统一协调控制事务。当本地事务提交回滚或者关闭连接时将会执行假操作,该代理的连接将由LCN连接池管理。
该模式的特点:
- 该模式对代码的嵌入性为低。 - 该模式仅限于本地存在连接对象且可通过连接对象控制事务的模块。 - 该模式下的事务提交与回滚是由本地事务方控制,对于数据一致性上有较高的保障。 - 该模式缺陷在于代理的连接需要随事务发起方一共释放连接,增加了连接占用的时间。
-
TCC模式:
TCC事务机制相对于传统事务机制(X/Open XA Two-Phase-Commit),其特征在于它不依赖资源管理器(RM)对XA的支持,而是通过对(由业务系统提供的)业务逻辑的调度来实现分布式事务。主要由三步操作,Try: 尝试执行业务、 Confirm:确认执行业务、 Cancel: 取消执行业务。
该模式的特点:
- 该模式对代码的嵌入性高,要求每个业务需要写三种步骤的操作。 - 该模式对有无本地事务控制都可以支持使用面广。 - 数据一致性控制几乎完全由开发者控制,对业务开发难度要求高。
-
TXC模式:
TXC模式命名来源于淘宝,实现原理是在执行 SQL 之前,先查询SQL的影响数据,然后保存执行的SQL快走信息和创建锁。当需要回滚的时候就采用这些记录数据回滚数据库,目前锁实现依赖 redis 分布式锁控制。
该模式的特点:
- 该模式同样对代码的嵌入性低。 - 该模式仅限于对支持SQL方式的模块支持。 - 该模式由于每次执行SQL之前需要先查询影响数据,因此相比LCN模式消耗资源与时间要多。 - 该模式不会占用数据库的连接资源。
LCN原理
这里引用一下官网的原理图:
总的来说,核心步骤就是创建事务组,假如事务组,通知事务组
创建事务组
- 是指在事务发起方开始执行业务代码之前先调用TxManager创建事务组对象,然后拿到事务标示GroupId的过程。
加入事务组
- 添加事务组是指参与方在执行完业务方法以后,将该模块的事务信息通知给TxManager的操作
通知事务组
- 是指在发起方执行完业务代码以后,将发起方执行结果状态通知给TxManager,TxManager将根据事务最终状态和事务组的信息来通知相应的参与模块提交或回滚事务,并返回结果给事务发起方。
集成springCloud
(ps:我这里使用的springboot版本是2.1.3)
<!----pom.xml 今天是2019.4.24 最新版本是5.0.2 ---> <properties> <codingapi.txlcn.version>5.0.2.RELEASE</codingapi.txlcn.version> </properties> <dependency> <groupId>com.codingapi.txlcn</groupId> <artifactId>txlcn-tc</artifactId> <version>${codingapi.txlcn.version}</version> </dependency> <dependency> <groupId>com.codingapi.txlcn</groupId> <artifactId>txlcn-tm</artifactId> <version>${codingapi.txlcn.version}</version> </dependency> <dependency> <groupId>com.codingapi.txlcn</groupId> <artifactId>txlcn-txmsg-netty</artifactId> <version>${codingapi.txlcn.version}</version> </dependency>
A启动类上加注解:@EnableDistributedTransaction 表明这是一个txmanager的client
@SpringBootApplication @EnableEurekaClient @EnableFeignClients @EnableDistributedTransaction @MapperScan("cn.iamcrawler.crawlergoddess.mapper") @ComponentScan("cn.iamcrawler.crawlergoddess,cn.iamcrawler.crawler_common.feign") public class CrawlerGoddessApplication { public static void main(String[] args) { SpringApplication.run(CrawlerGoddessApplication.class, args); } }
yml(ps 我把密码隐藏了,数据库我用的是postgresql,lcn默认的是mysql):
server: port: 9993 spring: datasource: url: jdbc:postgresql://www.iamcrawler.cn:5432/mft?characterEncoding=utf8&useUnicode=true&useSSL=false&serverTimezone=UTC username: postgres password: ** driver-class-name: org.postgresql.Driver redis: host: www.iamcrawler.cn port: 6379 password: ** database: 0 application: name: crawler-goddess rabbitmq: host: www.iamcrawler.cn port: 5672 username: liuliang password: ** jpa: properties: hibernate: jdbc: lob: non_contextual_creation: true database-platform: org.hibernate.dialect.PostgreSQL9Dialect # aop: # proxy-target-class: true eureka: client: service-url: defaultZone: http://localhost:9990/eureka/ init-db: true tx-lcn: client: manager-address: 127.0.0.1:8070 logger: enabled: true driver-class-name: ${spring.datasource.driver-class-name} jdbc-url: jdbc:postgresql://www.iamcrawler.cn:5432/mft?characterEncoding=UTF-8 username: ${spring.datasource.username} password: ${spring.datasource.password} logging: level: com: codingapi: debug
A模块代码示例:
@Transactional @LcnTransaction//表明使用lcn模式 public void testLcn(){ PgTestUser testUser = new PgTestUser(); testUser.setAge(1); testUser.setName("liuliang"); testUser.setRemark("要买东西"); testUser.setSalary(new BigDecimal(10)); this.save(testUser); PgOrder order = new PgOrder(); order.setAmount(new BigDecimal(10)); order.setItemName("小视频"); kindnessFeign.insertOne(order); logger.info("==============="); throw new RuntimeException(""); // logger.info("插入完毕...事务提交!"); }
B模块代码示例
@LcnTransaction @Transactional public Boolean insertOne(PgOrder pgOrder) { RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes(); HttpServletRequest request = requestAttributes == null ? null : ((ServletRequestAttributes) requestAttributes).getRequest(); // String groupId = TracingContext.tracing().groupId(); // String applicationId = Transactions.getApplicationId(); boolean save = pgOrderService.save(pgOrder); return save; }
然后调用即可,LCN5.0.2的lcn模式也4.1.0的TX模式很类似,就是不用标记isStart=true了,并且还支持TCC模式和TXC模式,TCC模式可以控制多个连接,比如A使用mysql,B使用Redis,C使用Mongodb,D模块使用postgresql,可以使用TCC模式。但是TCC模式需要有注意的地方。下一篇文章将结合源码仔细说明
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 使用 Camel 实现分布式企业应用集成
- 真正的持续集成:分布式代码仓库和依赖
- SpringBlade 2.5.0 发布,集成 Seata 支持分布式事务
- Spring Boot集成Hazelcast实现集群与分布式内存缓存
- 原 荐 缓存架构SpringBoot集成Curator实现zookeeper分布式锁
- Guns 旗舰版 2.3 发布,集成atomikos,解决分布式事务问题
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
赢在设计
[美] 洛芙迪 (Lance Loveday)、[美] 尼豪斯 (Sandra Niehaus) / 刘淼、枊靖、王卓昊 / 人民邮电出版社 / 2010-8 / 55.00
企业总是面临在网站设计和改进方面进行投资的抉择。怎样才能让有限的资金发挥出最大的效益呢?网站设计不应只是把网站做得赏心悦目,它更应该是提高经济收益和获得竞争优势的战略利器。是时候让网站发挥其潜能,以业务指标为导向来做设计决策,为提升网站收益而设计了。 作者凭借多年为众多网站做咨询工作的经验,为我们揭示了赢在设计的奥秘。它针对目前网站设计中存在的典型问题,先从宏观上探讨解决问题的战略手段,围绕......一起来看看 《赢在设计》 这本书的介绍吧!