Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

IDIEP-34
Author
Sponsor
Created

 

Status

Status
colour

Grey

Green
title

DRAFT

COMPLETED


Table of Contents

Motivation

Currently transactions are not supported by thin client protocol. 

Description

There are changes needed for protocol, server side, and client side to support transactions.

Protocol changes

Add new operations to the thin client protocol:

NameCodeDescription
OP_TX_START4000Start a new transaction
OP_TX_END4001End the transaction

OP_TX_START message format

Request
byte

Concurrency control:

0 - OPTIMISTIC

1 - PESSIMISTIC

-1 - use server's default value

byte

Isolation level:

0 - READ_COMMITTED

1 - REPEATABLE_READ

2 - SERIALIZABLE-1 - use server's default value

longTimeout (-1 - use server's default value)intNumber of entries participating in transaction (may be approximate). 0 - default value.
stringlabel


Response

intUnique per client connection transaction id. This id should be returned as parameter with OP_TX_END message and all messages of cache operations within the transaction.

OP_TX_END message format

Request
int

Transaction id.

bool

Commit flag.


Empty response.

Server-side changes

As a first step, to support transaction from the server side we can use the same approach as for JDBC: add a new worker to each ClientRequestHandler and process requests by this worker if the transaction is started explicitly. ClientRequestHandler is bound to client connection, so there will be 1:1 relation between client connection and thread, which process operations in a transaction.

Later, we can change the server-side implementation (no changes to the protocol or client-side implementations needed) to execute a transaction from the "client-connector" thread. This approach will be more effective since there will be no overhead to start additional threads. But before, we need to implement a mechanism to decouple transactions from the thread (when multiple transactions could be executed from the same thread). 

Client-side changes

Cache operations

We need to add a new field to requests header of all cache data manipulation operations (opcodes 1000-1020, 2000, 2002, 2004) to bind these operations with the transaction.

Proposed changes to cache operations request header format:

TypeDescription
intLength of payload
shortOperation code
longRequest id
intCache id
byteflags (new "under transaction" flag with bitmask 0x02 introduced, to indicate that operation performed under transaction)modified
intTransaction id (present only if "under transaction" flag is set, i.e. if flags & 0x02 != 0)added


Server-side changes

On the server side, we need to have the ability to decouple transactions from threads. We can do this by using transaction suspend/resume methods. Suspend/resume methods are only implemented for optimistic transactions now, so we need to implement this mechanism for pessimistic transactions first.

Using this approach there is no need to start any new thread to serve the transaction. All transaction control operations and all cache operations within transactions will be served by existing "client-connector" threads.

When the client sends OP_TX_START request, a new transaction is starting in a suspended state.

When the client performs a cache operation within a transaction, thread served this request resumes the transaction, processes cache operation and suspends the transaction again.

When the client sends OP_TX_END request, thread served this request resumes the transaction and commit or rollback it.

Client-side changes

The client must bind transaction and all cache operations which was made within this explicitly started transaction. We can implement transaction per thread approach on the thin client side as implemented now for the thick client. In this case, each transaction on the thin client side will be bound to a thread started this transaction. And each cache operation performed by this thread will be bound to the same transaction until the transaction is completed.

Also, the client Client implementation must review the logic of failover, since we can't silently change servers in case of connection error in the middle of the transaction.

If client allowed to use several concurrent transactions per connection it must support async request sending to server, otherwise, deadlock is possible (for example, when the first transaction lock the key, then the second transaction try to lock the same key, blocks and lock the connection).

Proposed new interfaces for java thin client:

Code Block
languagejava
titleClientTransactionscollapsetrue
public interface ClientTransactions {
    public ClientTransaction txStart(); // Start tx with client default values of concurrency, isolation and timeout properties.
    public ClientTransaction txStart(TransactionConcurrency concurrency, TransactionIsolation isolation); // Start tx with default timeout.
    public ClientTransaction txStart(TransactionConcurrency concurrency, TransactionIsolation isolation, long timeout, int txSize);
    public ClientTransactions withLabel(String lb);
}

...

Code Block
languagejava
titleClientTransaction
public interface ClientTransaction extends AutoCloseable {
    public void commit();
    public void rollback();
    public void close();
}

Risks and Assumptions

Without decoupling transactions from the thread for each connection which starts transactions explicitly new dedicated thread will be added (we already have one dedicated NIO thread per client connection and also thread pool to process client messages) this will bring extra pressure to the server.

To configure client default concurrency, isolation and timeout values for connection it is proposed to create new configuration class:

Code Block
languagejava
titleClientTransactionConfiguration
public class ClientTransactionConfiguration {
    public static final TransactionConcurrency DFLT_TX_CONCURRENCY = TransactionConcurrency.PESSIMISTIC;
    public static final TransactionIsolation DFLT_TX_ISOLATION = TransactionIsolation.REPEATABLE_READ;
    public static final long DFLT_TRANSACTION_TIMEOUT = 0;

    public TransactionConcurrency getDefaultTxConcurrency();
	public ClientTransactionConfiguration setDefaultTxConcurrency(TransactionConcurrency dfltConcurrency)

    public TransactionIsolation getDefaultTxIsolation();
    public ClientTransactionConfiguration setDefaultTxIsolation(TransactionIsolation dfltIsolation);

    public long getDefaultTxTimeout();
	public ClientTransactionConfiguration setDefaultTxTimeout(long dfltTxTimeout);
}

This transaction configuration can be used when the client connection is created (as a property of ClientConfiguration class).

Risks and Assumptions

//We can't support concurrent transactions per connection on the client side without fundamental changes to the current protocol (cache operation doesn't bound to transaction or thread and the server doesn't know which thread on the client side do this cache operation). So, now we can only support one active transaction per connection.

Discussion Links

http://apache-ignite-developers.2346864.n4.nabble.com/Thin-client-transactions-support-td27761.html

Reference Links

// Links to various reference documents, if applicable.

Tickets

Jira
serverASF JIRA
columnskey,summary,type,created,updated,due,assignee,reporter,priority,status,resolution
maximumIssues20
jqlQueryproject = Ignite AND labels IN (iep-34) ORDER BY status
serverId5aa69414-a9e9-3523-82ec-879b028fb15b