Skip to content

Transaction support #975

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
13 tasks done
zhicwu opened this issue Jul 1, 2022 · 3 comments · Fixed by #1008, #1278 or #1285
Closed
13 tasks done

Transaction support #975

zhicwu opened this issue Jul 1, 2022 · 3 comments · Fixed by #1008, #1278 or #1285

Comments

@zhicwu
Copy link
Contributor

zhicwu commented Jul 1, 2022

Server

  • Transaction ID: Tuple(snapshot_version UInt64, local_txid_counter UInt64, host_id UUID)
  • functions: transactionID(), transactionLatestSnapshot(), transactionOldestSnapshot()
  • settings: throw_on_unsupported_query_inside_transaction, wait_changes_become_visible_after_commit_mode, implicit_transaction
  • statements: begin transaction, commit, rollback, set transaction snapshot <snapshot id>, kill transaction where tid=<transaction id>

Java Client

  • new client option transaction_timeout, defaults to session_timeout
  • add ClickHouseTransaction with methods for begin/commit/rollback transaction and snapshot
  • add ClickHouseRequestManager for generating query id and session id as well as transaction creation
  • enhance ClickHouseRequest by adding methods getTransaction and setTransaction - multiple requests can take part in one transaction
  • throw ClickHouseTransactionException for Code: 649. DB::Exception: Cannot execute query because current transaction failed. Expecting ROLLBACK statement. (INVALID_TRANSACTION) - server will rollback automatically but still needs client to explicitly to acknowledge that by issue rollback(using connection.rollback())
  • always create new session when begin transaction and enforce session_check until transaction completed
  • consider transaction in retry and failover(avoid node switching)

JDBC Driver

  • new JDBC option transactionSupport (defaults to false)
  • use implicit_transaction in auto commit mode, fallback to TCL when it's not supported
  • replace FakeTransaction when transaction support is enabled
  • change default transaction isolation level to repeatable-read(why?)
  • parse TCL to maintain transaction consistency between server and client in 0.3.3?
  • update SIT base classes in 0.3.3 to use docker-compose instead of standalone container and then enable tests for HA and TX in CI
@zhicwu
Copy link
Contributor Author

zhicwu commented Jul 27, 2022

Usage(as of 0.3.2-patch11):

  • Java Client

    ClickHouseNode server = ClickHouseNode.of("http://localhost:48011/system?transactionSupport");
    try (ClickHouseClient client = ClickHouseClient.newInstance(server.getProtocol())) {
        // implicit transaction
        try (ClickHouseResponse response = client.connect(server)
            .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
            .query("select 1")
            // blocking call to create and start a new transaction, issue query, and then commit/rollback automatically
            .executeWithinTransaction()) {
            ...
        }
    
        ClickHouseRequest<?> reqWithManualTx = client.connect(server)
            .format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
            .transaction() // create a new transaction and call its begin() method right now
            .query("select 1");
        try (ClickHouseResponse response = reqWithManualTx.executeAndWait()) {
            ...
        }
        reqWithManualTx.getTransaction().commit(); // commit the transaction right away
    }
  • JDBC Driver

    // auto-commit
    try (Connection conn = DriverManager.getConnection("jdbc:ch:http://localhost:48011/system?transactionSupport");
        Statement stmt = conn.createStatement()) {
        stmt.executeQuery("select 1");
        ...
    }
    
    // manual
    try (Connection conn = DriverManager.getConnection("jdbc:ch:http://localhost:48011/system?!autoCommit&transactionSupport");
        Statement stmt = conn.createStatement()) {
        stmt.executeQuery("select 1");
        conn.commit();
    }

Performance penalty for transaction support is acceptable(on client side):

image

@hantaoliulinux
Copy link

Hello, can you provide an example of transactional data insertion using PreparedStatement about JDBC Driver?

@zhicwu
Copy link
Contributor Author

zhicwu commented Mar 13, 2023

Hello, can you provide an example of transactional data insertion using PreparedStatement about JDBC Driver?

Hi @hantaoliulinux, did you run into any issue using above examples? The usage is same for Statement and PreparedStatement. FYI, transaction won't start in 0.4.0 and 0.4.1, please use v0.3.2-patch11(or wait for 0.4.2) for transaction support.

@zhicwu zhicwu linked a pull request Mar 13, 2023 that will close this issue
3 tasks
@zhicwu zhicwu reopened this Mar 13, 2023
@zhicwu zhicwu linked a pull request Mar 16, 2023 that will close this issue
3 tasks
mixayloff-dimaaylov added a commit to mixayloff-dimaaylov/logserver-spark that referenced this issue Mar 25, 2023
Транзакции пока не поддерживаются ClickHouse.

Ref: ClickHouse/clickhouse-java#975
Ref: ClickHouse/clickhouse-java#1008 (comment)
mixayloff-dimaaylov added a commit to mixayloff-dimaaylov/logserver-spark that referenced this issue Apr 3, 2023
Транзакции пока не поддерживаются ClickHouse.

Ref: ClickHouse/clickhouse-java#975
Ref: ClickHouse/clickhouse-java#1008 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants