Coder Social home page Coder Social logo

dtm-labs / dtmcli-java Goto Github PK

View Code? Open in Web Editor NEW
23.0 13.0 17.0 222 KB

Official java client for distributed transaction framework dtm

License: MIT License

Java 100.00%
distributed-transaction tcc saga dtm distributed database transaction transactions

dtmcli-java's Introduction

dtmcli-java MIT

English | 简体中文

dtmcli-java is the Java client SDK for distributed transaction manager dtm

What is DTM

DTM is a distributed transaction framework which provides cross-service eventual data consistency. It provides saga, tcc, xa, 2-phase message, outbox patterns for a variety of application scenarios. It also supports multiple languages and multiple store engine to form up a transaction as following:

function-picture

Features

  • Support for multiple languages: Go, Java, PHP, C#, Python, Nodejs SDKs
  • Support for multiple transaction patterns: SAGA, TCC, XA
  • Support for OutBox pattern: 2-phase messages, a more elegant solution than OutBox
  • Support for multiple database transactions: Mysql, Redis, MongoDB, Postgres, TDSQL, etc.
  • Support for multiple storage engines: Mysql (common), Redis (high performance), MongoDB (in planning)
  • Support for multiple microservices architectures: go-zero, go-kratos/kratos, polarismesh/polaris
  • Support for high availability and easy horizontal scaling

Usage

Step 1: Determine the version

  1. Springcloud Projects
  • If the version of springboot >= 2.4.0, choose a corresponding version of dtmcli-springcloud.
  • If the version of springboot <> 2.4.0, use dtmcli-java, it provide the interfaces for micro-services, please set the configuration for nacos.
  1. Not Springcloud Projects.
  • use dtmcli-java,and set your configurations.
artifact version dtmcli-java version remark
dtmcli-springcloud 2.1.4.1 2.4.0 <= springboot version < 2.5.13 for springboot >= 2.5.0,please set spring.cloud.compatibility-verifier.enabled=false
dtmcli-springcloud 2.1.4.2 2.6.0 <= springboot version < 2.6.latest
dtmcli-java 2.1.4 others

Step 2: Add Dependencies

Maven:

<dependency>
	<groupId>io.github.dtm-labs</groupId>
	<artifactId>dtmcli-springcloud</artifactId>
	<version>${dtmcli.version}</version>
</dependency>

Gradle:

dependencies {
	        implementation 'io.github.dtm-labs:dtmcli-springcloud:${dtmcli.version}'
	}

Step 3:Configure dtmcli-java

If you are using dtmcli-java,new a file named dtm-conf.properties

  • Case 1: Using naceos
serverAddr=127.0.0.1:8848
username=nacos
password=nacos
namespace=c3dc917d-906a-429d-90a9-85012b41014e
dtm.service.name=dtmService
dtm.service.registryType=nacos
  • Case 2: Connect to dtmsvr directly
dtm.ipport=127.0.0.1:36789

Sample

@RequestMapping("testTcc")
    public String testTcc() {
        // new dtm clinet
        DtmClient dtmClient = new DtmClient(ipPort);
        //create TCC transaction
        try {
            dtmClient.tccGlobalTransaction(dtmClient.genGid(), TccTestController::tccTrans);
        } catch (Exception e) {
            log.error("tccGlobalTransaction error", e);
            return "fail";
        }
        return "success";
    }

/**
     * define TCC sub-transactions by calling callBranch
     *
     * @param tcc
     * @return
     * @see TransController
     */
    public static void tccTrans(Tcc tcc) throws Exception {
        Response outResponse = tcc
                .callBranch("", svc + "/TransOutTry", svc + "/TransOutConfirm", svc + "/TransOutCancel");
        log.info("outResponse:{}", outResponse);
        Response inResponse = tcc.callBranch("", svc + "/TransInTry", svc + "/TransInConfirm", svc + "/TransInCancel");
        log.info("inResponse:{}", inResponse);
    }

Complete Sample

Sample for dtmcli-java

dtmcli-java-sample dtmcli-java-sample-use-configuration

Sample for dtmcli-springcloud

dtmcli-java-spring-sample

dtmcli-java's People

Contributors

8q757 avatar babyfish-ct avatar catcherwong avatar horselk avatar li-xiao-shuang avatar yedf2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dtmcli-java's Issues

阅读代码发现的4个问题

看了一下Java SDK的源码,发现如下几个问题(由大到小排序)

---大问题---

  1. 为完成本地事务屏障,私自打开和关闭JDBC链接,导致和原有Spring 的连接/事务管理功能脱钩。实际项目中,用户代码不太可能直接基于指定的JDBC连接执行,一般是基于Spring技术栈提供的更高级的数据访问技术操作,这会导致SDK保证事务屏障的JDBC连接和实际业务的连接并非同一连接。

---小问题---

  1. 本地事务屏障只支持MySQL

  2. 不会自动创建barrier表

tcc:get response.body().string() closed

tcc模式下想要解析 response的body内容
但response.body().string()只能请求一次,在dtm内已经调用过此方法
请问是否还有其他解决方案可以获取返回值吗?

public static void checkResult(Response response) throws Exception { if (response.code() >= 400) { throw new FailureException(response.message()); } else { ResponseBody body = response.body(); String result; if (body != null && !StringUtils.isBlank(result = body.string())) { if (result.contains("FAILURE")) { throw new FailureException("Service returned failed"); } } else { throw new FailureException("response is null"); } } }

BUG: tcc query-string

BUG:
FILE: tcc.java

HttpResponse response2 = HttpRequest.post(tryUrl)
                    .body(JSONUtil.toJsonStr(body))
                    .form(paramMap2) // HERE
                    .execute();

maybe FIX :

            HttpResponse response2 = HttpRequest.post(tryUrl + "?" + mapToQueryString(paramMap2))
                    .body(JSONUtil.toJsonStr(body))
                    //.form(paramMap2)
                    .execute();

  private static String mapToQueryString(Map<String, Object> queryParams) {
        String queryString = queryParams.entrySet().stream()
                .map(e -> e.getKey() + "=" + e.getValue())
                .collect(Collectors.joining("&"));
        return URLUtil.encode(queryString);
    }

dtmcli-core没有实现Saga模式下的空补偿,只实现了TCC模式下的空补偿

// pub.dtm.client.barrier.BranchBarrier#insertBarrier

private boolean insertBarrier(Connection connection) throws SQLException {
log.info("insert barrier {}", this);
if (Objects.isNull(connection)) {
return false;
}
PreparedStatement preparedStatement = null;
try {
String sql = "insert ignore into barrier(trans_type, gid, branch_id, op, barrier_id, reason) values(?,?,?,?,?,?)";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, this.getTransTypeEnum().getValue());
preparedStatement.setString(2, this.getGid());
preparedStatement.setString(3, branchId);
preparedStatement.setString(4, op);
preparedStatement.setString(5, String.format("%02d", barrierId));
preparedStatement.setString(6, op);

        if (preparedStatement.executeUpdate() == 0) {
            return false;
        }
        if (ParamFieldConstants.CANCEL.equals(op)) {
            int opIndex = 4;
            preparedStatement.setString(opIndex, ParamFieldConstants.TRY);
            if (preparedStatement.executeUpdate() > 0) {
                return false;
            }
        }
    } finally {
        if (Objects.nonNull(preparedStatement)) {
            preparedStatement.close();
        }
    }
    return true;
}

这个地方,只判断了ParamFieldConstants.CANCEL.equals(op),而Saga模式的补偿op是compensate,不是cancel

missing java-sample-demo sql script

CREATE TABLE barrier (
id bigint NOT NULL AUTO_INCREMENT,
user_id int DEFAULT NULL,
amount int DEFAULT NULL,
trans_type varchar(255) DEFAULT NULL,
gid varchar(100) DEFAULT NULL,
branch_id varchar(100) DEFAULT NULL,
op varchar(255) DEFAULT NULL,
barrier_id varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
reason varchar(255) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.