Provide Best Programming Tutorials

TCC事务机制简介

关于TCC(Try-Confirm-Cancel)的概念,最早是由Pat Helland于2007年发表的一篇名为《Life beyond Distributed Transactions:an Apostate’s Opinion》的论文提出。在该论文中,TCC还是以Tentative-Confirmation-Cancellation作为名称;正式以Try-Confirm-Cancel作为名称的,可能是Atomikos(Gregor Hohpe所著书籍《Enterprise Integration Patterns》中收录了关于TCC的介绍,提到了Atomikos的Try-Confirm-Cancel,并认为二者是相似的概念)。 国内最早关于TCC的报道,应该是InfoQ上对阿里程立博士的一篇采访。经过程博士的这一次传道之后,TCC在国内逐渐被大家广为了解并接受。相应的实现方案和开源框架也先后被发布出来,ByteTCC就是其中之一。 TCC事务机制相对于传统事务机制(X/Open XA Two-Phase-Commit),其特征在于它不依赖资源管理器(RM)对XA的支持,而是通过对(由业务系统提供的)业务逻辑的调度来实现分布式事务。 对于业务系统中一个特定的业务逻辑S,其对外提供服务时,必须接受一些不确定性,即对业务逻辑执行的一次调用仅是一个临时性操作,调用它的消费方服务M保留了后续的取消权。如果M认为全局事务应该rollback,它会要求取消之前的临时性操作,这将对应S的一个取消操作;而当M认为全局事务应该commit时,它会放弃之前临时性操作的取消权,这对应S的一个确认操作。 每一个初步操作,最终都会被确认或取消。因此,针对一个具体的业务服务,TCC事务机制需要业务系统提供三段业务逻辑:初步操作Try、确认操作Confirm、取消操作Cancel。 1. 初步操作(Try)TCC事务机制中的业务逻辑(Try),从执行阶段来看,与传统事务机制中业务逻辑相同。但从业务角度来看,却不一样。TCC机制中的Try仅是一个初步操作,它和后续的确认一起才能真正构成一个完整的业务逻辑。可以认为 1[传统事务机制]的业务逻辑 = [TCC事务机制]的初步操作(Try) + [TCC事务机制]的确认逻辑(Confirm)。 TCC机制将传统事务机制中的业务逻辑一分为二,拆分后保留的部分即为初步操作(Try);而分离出的部分即为确认操作(Confirm),被延迟到事务提交阶段执行。TCC事务机制以初步操作(Try)为中心的,确认操作(Confirm)和取消操作(Cancel)都是围绕初步操作(Try)而展开。因此,Try阶段中的操作,其保障性是最好的,即使失败,仍然有取消操作(Cancel)可以将其不良影响进行回撤。 2. 确认操作(Confirm)确认操作(Confirm)是对初步操作(Try)的一个补充。当TCC事务管理器决定commit全局事务时,就会逐个执行初步操作(Try)指定的确认操作(Confirm),将初步操作(Try)未完成的事项最终完成。 3. 取消操作(Cancel)取消操作(Cancel)是对初步操作(Try)的一个回撤。当TCC事务管理器决定rollback全局事务时,就会逐个执行初步操作(Try)指定的取消操作(Cancel),将初步操作(Try)已完成的事项全部撤回。 在传统事务机制中,业务逻辑的执行和事务的处理,是在不同的阶段由不同的部件来完成的:业务逻辑部分访问资源实现数据存储,其处理是由业务系统负责;事务处理部分通过协调资源管理器以实现事务管理,其处理由事务管理器来负责。二者没有太多交互的地方,所以,传统事务管理器的事务处理逻辑,仅需要着眼于事务完成(commit/rollback)阶段,而不必关注业务执行阶段。 而在TCC事务机制中的业务逻辑处理和事务处理,其关系就错综复杂:业务逻辑(Try/Confirm/Cancel)阶段涉及所参与资源事务的commit/rollback;全局事务commit/rollback时又涉及到业务逻辑(Try/Confirm/Cancel)的执行。其中关系,本站将另行撰文详细介绍,敬请关注!

Continue Reading

常用的分布式事务解决方案

什么是事务? 事务由一组操作构成,我们希望这组操作能够全部正确执行,如果这一组操作中的任意一个步骤发生错误,那么就需要回滚之前已经完成的操作。也就是同一个事务中的所有操作,要么全都正确执行,要么全都不要执行。 事务的四大特性 ACID 说到事务,就不得不提一下事务著名的四大特性。 原子性 原子性要求,事务是一个不可分割的执行单元,事务中的所有操作要么全都执行,要么全都不执行。 一致性 一致性要求,事务在开始前和结束后,数据库的完整性约束没有被破坏。 隔离性 事务的执行是相互独立的,它们不会相互干扰,一个事务不会看到另一个正在运行过程中的事务的数据。 持久性 持久性要求,一个事务完成之后,事务的执行结果必须是持久化保存的。即使数据库发生崩溃,在数据库恢复后事务提交的结果仍然不会丢失。 注意:事务只能保证数据库的高可靠性,即数据库本身发生问题后,事务提交后的数据仍然能恢复;而如果不是数据库本身的故障,如硬盘损坏了,那么事务提交的数据可能就丢失了。这属于『高可用性』的范畴。因此,事务只能保证数据库的『高可靠性』,而『高可用性』需要整个系统共同配合实现。 事务的隔离级别 这里扩展一下,对事务的隔离性做一个详细的解释。 在事务的四大特性ACID中,要求的隔离性是一种严格意义上的隔离,也就是多个事务是串行执行的,彼此之间不会受到任何干扰。这确实能够完全保证数据的安全性,但在实际业务系统中,这种方式性能不高。因此,数据库定义了四种隔离级别,隔离级别和数据库的性能是呈反比的,隔离级别越低,数据库性能越高,而隔离级别越高,数据库性能越差。 事务并发执行会出现的问题 我们先来看一下在不同的隔离级别下,数据库可能会出现的问题: 更新丢失 当有两个并发执行的事务,更新同一行数据,那么有可能一个事务会把另一个事务的更新覆盖掉。 当数据库没有加任何锁操作的情况下会发生。 脏读 一个事务读到另一个尚未提交的事务中的数据。 该数据可能会被回滚从而失效。 如果第一个事务拿着失效的数据去处理那就发生错误了。 不可重复读 不可重复度的含义:一个事务对同一行数据读了两次,却得到了不同的结果。它具体分为如下两种情况: 虚读:在事务1两次读取同一记录的过程中,事务2对该记录进行了修改,从而事务1第二次读到了不一样的记录。幻读:事务1在两次查询的过程中,事务2对该表进行了插入、删除操作,从而事务1第二次查询的结果发生了变化。 不可重复读…

Continue Reading

maven-wrapper介绍

环境依赖 JAVA_HOME 环境变量需要配置 maven-wrapper的应用 使用https://start.spring.io/生成Spring Boot初始项目时,发现其中有几个奇怪的文件 ├── .mvn │ └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── mvnw └── mvnw.cmd 复制代码 maven-wrapper干嘛用的? 先来看看传统maven的使用流程 传统使用maven需要先到官网上下载配置环境变量把mvn可执行文件路径加入到环境变量,以便之后使用直接使用mvn命令。另外项目pom.xml文件描述的依赖文件默认是下载在用户目录下的.m2文件下的repository目录下。再次,如果需要更换maven的版本,需要重新下载maven并替换环境变量path中的maven路径。 现在有了maven-wrapper,会获得以下特性 执行mvnw比如mvnw clean ,如果本地没有匹配的maven版本,直接会去下载maven,放在用户目录下的.m2/wrapper中并且项目的依赖的jar包会直接放在项目目录下的repository目录,这样可以很清晰看到当前项目的依赖文件。如果需要更换maven的版本,只需要更改项目当前目录下.mvn/wrapper/maven-wrapper.properties的distributionUrl属性值,更换对应版本的maven下载地址。mvnw命令就会自动重新下载maven。可以说带有mvnw文件的项目,除了额外需要配置 java环境外,只需要使用本项目的mvnw脚本就可以完成编译,打包,发布等一系列操作。 在项目初始化mvnw文件 如果你的项目没有mvnw文件,需要先下载maven,并把mvn可执行文件路径需加入的PATH中。然后执行以下命令,就会自动生成mvnw相关一系列文件…

Continue Reading

使用Beyond Compare作为git mergetool的默认对比工具 For Mac

第一步 点击下载下载Beyond Compare 第二步 image.png 第三步 Mac上需要在user目录下的.gitconfig文件中加入下面的配置: 或用终端打开.gitconfig文件在里面添加下面的配置, 终端指令 $git config --edit --global [diff] tool = bcomp [difftool "bcomp"] cmd = \"/usr/local/bin/bcomp\" \"$LOCAL\" \"$REMOTE\" [difftool] prompt = false [merge] tool…

Continue Reading
Close Menu