One of TCC distributed transactions-the latest version of tcc-transaction-1.2.x integrates spring cloud + dubbo + zookeeper

Tcc-transaction is the open source tcc distributed transaction framework of github. Compared with other tcc open source frameworks, tcc-transaction ranks first in the number of stars. It can be processed asynchronously or synchronously.

Github User Guide 1.2.x: https://github.com/changmingxie/tcc-transaction/wiki/%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%971.2.x

tcc three stages

Try: Try to execute business

完成所有业务检查(一致性)
预留必须业务资源(准隔离性)

Confirm: Confirm execution of business

真正执行业务
不作任何业务检查
只使用Try阶段预留的业务资源
Confirm操作满足幂等性

Cancel: Cancel execution of business

释放Try阶段预留的业务资源
Cancel操作满足幂等性

maven configuration

			<!--tcc-transaction核心包-->
			<dependency>
				<groupId>org.mengyun</groupId>
				<artifactId>tcc-transaction-spring</artifactId>
				<version>1.2.12</version>
			</dependency>
			<!--tcc-transaction整合dubbo核心包-->
			<dependency>
				<groupId>org.mengyun</groupId>
				<artifactId>tcc-transaction-dubbo</artifactId>
				<version>1.2.12</version>
			<exclusions>
				<exclusion>
					<groupId>org.apache.dubbo</groupId>
					<artifactId>dubbo</artifactId>
				</exclusion>
				<exclusion>
					<artifactId>zookeeper</artifactId>
					<groupId>org.apache.zookeeper</groupId>
				</exclusion>
				<exclusion>
					<artifactId>curator-recipes</artifactId>
					<groupId>org.apache.curator</groupId>
				</exclusion>
			</exclusions>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
				<version>2.2.1.RELEASE</version>
			</dependency>
			<dependency>
	            <groupId>com.alibaba.cloud</groupId>
	            <artifactId>spring-cloud-starter-dubbo</artifactId>
	            <version>2.2.1.RELEASE</version>
	            <exclusions>
	                <exclusion>
	                    <groupId>org.apache.dubbo</groupId>
	                    <artifactId>dubbo</artifactId>
	                </exclusion>
	            </exclusions>
	        </dependency>
	        <dependency>
	            <groupId>org.apache.dubbo</groupId>
	            <artifactId>dubbo</artifactId>
	            <version>2.7.7</version>
	        </dependency>
		</dependency>

First, you need to configure the config of the tcc service and the remote tcc service

tcc service configuration

@Configuration
public class TccConfig {
    
    

    @Bean
    public DefaultRecoverConfig defaultRecoverConfig(){
    
    
        DefaultRecoverConfig defaultRecoverConfig = new DefaultRecoverConfig();
        defaultRecoverConfig.setMaxRetryCount(30);   //最大重试次数
        defaultRecoverConfig.setRecoverDuration(30); //恢复持续时间
        defaultRecoverConfig.setCronExpression("0/30 * * * * ?"); //每30秒检查一次是否需要恢复(检查对应的日志表有无需要恢复的数据)//每30秒检查一次是否需要恢复
        defaultRecoverConfig.setDelayCancelExceptions(Sets.newHashSet(org.apache.dubbo.remoting.TimeoutException.class));
        return defaultRecoverConfig;
    }

    @Bean("transactionRepository")
    public SpringJdbcTransactionRepository springJdbcTransactionRepository(){
    
    
        SpringJdbcTransactionRepository springJdbcTransactionRepository = new SpringJdbcTransactionRepository();

        springJdbcTransactionRepository.setDomain("CONSUMER");    //domain
        springJdbcTransactionRepository.setTbSuffix("_CONSUMER"); //配置tcc日志表名称后缀:这里为:tcc_transaction_consumer

        //tcc所需分布式事务日志数据源(也可以使用其他数据源框架)
        HikariDataSource hikariDataSource = new HikariDataSource();
        hikariDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        hikariDataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/tcc?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=CTT");
        hikariDataSource.setUsername("root");
        hikariDataSource.setPassword("root");
        springJdbcTransactionRepository.setDataSource(hikariDataSource);

        return springJdbcTransactionRepository;
    }

}

Remote tcc service configuration, only need to modify the following two codes, other configurations are the same

		springJdbcTransactionRepository.setDomain("PROVIDER");
        springJdbcTransactionRepository.setTbSuffix("_PROVIDER"); //配置tcc日志表名称后缀:这里为:tcc_transaction_provider
  1. service defines the three stages of tcc service
    asyncConfirm = false:是否异步处理confirm阶段,默认false,也就是同步处理
    asyncCancel = false:是否异步处理cancel阶段,默认false,也就是同步处理
@Service
public class TccService{
    
    
	
	@DubboReference(check = false, retries = 0, timeout = 30000) //dubbo rpc远程过程调用
	private TestService testService;
	
 	@Override
    @Transactional
    @Compensable(confirmMethod = "commit", cancelMethod = "rollback", asyncConfirm = false, asyncCancel = false, delayCancelExceptions = {
    
    SocketTimeoutException.class, org.apache.dubbo.remoting.TimeoutException.class})
    public void doTry(@UniqueIdentity TransactionContext transactionContext, String accountNo, String to, BigDecimal amount) {
    
    
    	//try阶段
    	testService.remoteDoTry(transactionContext, accountNo, amount);
	}
	//如果try阶段成功,commit阶段必须成功,如果commit阶段抛出异常,则会重试commit阶段
 	@Transactional
    public void commit(TransactionContext transactionContext, String accountNo, String to, BigDecimal amount) {
    
    
    	//commit阶段
	}
 	@Transactional
    public void rollback(TransactionContext transactionContext, String accountNo, String to, BigDecimal amount) {
    
    
    	//rollback阶段
	}

Controller call:

@RestController
public class TestController {
    
    

	@Autowired
	private TccService tccService;
	
    @GetMapping("tcc")
    @ResponseBody
    public String tcc(String from, String to, BigDecimal amount) throws Exception {
    
    
        try{
    
    
            tccService.doTry(null, from, to, amount);
            return "success";
        } catch (Exception e){
    
    
            return "fail:" + e.getMessage();
        } finally {
    
    
            System.out.println("success finally");
        }
    }
}
  1. service defines three stages of remote tcc service
 	@Override
    @Transactional
    @Compensable(confirmMethod = "remoteCommit", cancelMethod = "remoteRollback", asyncConfirm = false, asyncCancel = false, delayCancelExceptions = {
    
    SocketTimeoutException.class, org.apache.dubbo.remoting.TimeoutException.class})
    public void remoteDoTry(@UniqueIdentity TransactionContext transactionContext, String accountNo, BigDecimal amount) {
    
    
    	//try阶段
	}
	//如果try阶段成功,commit阶段必须成功,如果commit阶段抛出异常,则会重试commit阶段
 	@Transactional
    public void remoteCommit(TransactionContext transactionContext, String accountNo, BigDecimal amount) {
    
    
    	//commit阶段
	}
 	@Transactional
    public void remoteRollback(TransactionContext transactionContext, String accountNo, BigDecimal amount) {
    
    
    	//rollback阶段
	}

TestService interface, pay attention to the @Compensableannotation on the remote interface

	@Compensable
    void remoteDoTry(TransactionContext transactionContext, String accountNo, BigDecimal amount);

The core code has been completed, configure the startup class

@SpringBootApplication
@EnableDiscoveryClient
@EnableDubbo 			 //启动dubbo配置与注解
@EnableAspectJAutoProxy  //启动切面类
@ImportResource(locations = {
    
    "classpath:tcc-transaction.xml", "classpath:tcc-transaction-dubbo.xml"}) //加载框架tcc-transaction配置
public class Application {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(Application .class, args);
    }

}

tcc database configuration

Tcc configuration database, because the database name configured as a front tcc, and tcc service configuration table suffix _CONSUMER, remote tcc service configuration table suffix _PROVIDER, so tcc create two tables in the database, the following is sql script
Insert picture description here
sql script, fields are The same, the only difference is the table name suffix

CREATE TABLE `tcc_transaction_consumer` (
  `TRANSACTION_ID` int(11) NOT NULL AUTO_INCREMENT,
  `DOMAIN` varchar(100) DEFAULT NULL,
  `GLOBAL_TX_ID` varbinary(32) NOT NULL,
  `BRANCH_QUALIFIER` varbinary(32) NOT NULL,
  `CONTENT` varbinary(8000) DEFAULT NULL,
  `STATUS` int(11) DEFAULT NULL,
  `TRANSACTION_TYPE` int(11) DEFAULT NULL,
  `RETRIED_COUNT` int(11) DEFAULT NULL,
  `CREATE_TIME` datetime DEFAULT NULL,
  `LAST_UPDATE_TIME` datetime DEFAULT NULL,
  `VERSION` int(11) DEFAULT NULL,
  `IS_DELETE` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`TRANSACTION_ID`),
  UNIQUE KEY `UX_TX_BQ` (`GLOBAL_TX_ID`,`BRANCH_QUALIFIER`)
) ENGINE=InnoDB AUTO_INCREMENT=378 DEFAULT CHARSET=utf8;

CREATE TABLE `tcc_transaction_provider` (
  `TRANSACTION_ID` int(11) NOT NULL AUTO_INCREMENT,
  `DOMAIN` varchar(100) DEFAULT NULL,
  `GLOBAL_TX_ID` varbinary(32) NOT NULL,
  `BRANCH_QUALIFIER` varbinary(32) NOT NULL,
  `CONTENT` varbinary(8000) DEFAULT NULL,
  `STATUS` int(11) DEFAULT NULL,
  `TRANSACTION_TYPE` int(11) DEFAULT NULL,
  `RETRIED_COUNT` int(11) DEFAULT NULL,
  `CREATE_TIME` datetime DEFAULT NULL,
  `LAST_UPDATE_TIME` datetime DEFAULT NULL,
  `VERSION` int(11) DEFAULT NULL,
  `IS_DELETE` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`TRANSACTION_ID`),
  UNIQUE KEY `UX_TX_BQ` (`GLOBAL_TX_ID`,`BRANCH_QUALIFIER`)
) ENGINE=InnoDB AUTO_INCREMENT=378 DEFAULT CHARSET=utf8;

Finally, attach a picture of using the apache jmeter stress test tool: the test is 100 threads, each thread has a throughput of 10, and the test data is accurate:
Insert picture description here
Insert picture description here
调用处理次数1000次没有问题,数据库数据也没有问题 !

At this point, the tcc distributed transaction is complete. If you still have questions, you can leave a message and you will answer as soon as you see it. Helpful friends 点个赞-点个赞-点个赞, refills~

Guess you like

Origin blog.csdn.net/a251628111/article/details/107203846