Update autocommit mode and transaction state

The transaction state only reflects explicitly started transactions.
Thus, by looking at the autocommit mode and the transaction state a
component can figure out whether the current statement will be committed
or not.
This commit is contained in:
Johan Wikman 2016-10-25 12:36:07 +03:00
parent 041df39819
commit f961f87e5e
3 changed files with 52 additions and 22 deletions

View File

@ -83,8 +83,6 @@ typedef enum
typedef enum
{
/*< The current transaction state is not known. */
SESSION_TRX_UNKNOWN = 0,
/*< There is no on-going transaction. */
SESSION_TRX_INACTIVE = SESSION_TRX_INACTIVE_BIT,
/*< A transaction is active. */
@ -241,6 +239,20 @@ void enable_session_timeouts();
/**
* Get the transaction state of the session.
*
* Note that this tells only the state of @e explicitly started transactions.
* That is, if @e autocommit is OFF, which means that there is always an
* active transaction that is ended with an explicit COMMIT or ROLLBACK,
* at which point a new transaction is started, this function will still
* return SESSION_TRX_INACTIVE, unless a transaction has explicitly been
* started with START TRANSACTION.
*
* Likewise, if @e autocommit is ON, which means that every statement is
* executed in a transaction of its own, this will return false, unless a
* transaction has explicitly been started with START TRANSACTION.
*
* @note The return value is valid only if either a router or a filter
* has declared that it needs RCAP_TYPE_TRANSACTION_TRACKING.
*
* @param ses The SESSION object.
* @return The transaction state.
*/
@ -259,7 +271,12 @@ session_trx_state_t session_get_trx_state(const SESSION* ses);
session_trx_state_t session_set_trx_state(SESSION* ses, session_trx_state_t new_state);
/**
* Tells whether a transaction is active.
* Tells whether an explicit transaction is active.
*
* @see session_get_trx_state
*
* @note The return value is valid only if either a router or a filter
* has declared that it needs RCAP_TYPE_TRANSACTION_TRACKING.
*
* @return True if a transaction is active, false otherwise.
*/
@ -271,6 +288,11 @@ static inline bool session_trx_is_active(const SESSION* ses)
/**
* Tells whether an explicit READ ONLY transaction is active.
*
* @see session_get_trx_state
*
* @note The return value is valid only if either a router or a filter
* has declared that it needs RCAP_TYPE_TRANSACTION_TRACKING.
*
* @return True if an explicit READ ONLY transaction is active,
* false otherwise.
*/
@ -282,6 +304,11 @@ static inline bool session_trx_is_read_only(const SESSION* ses)
/**
* Tells whether an explicit READ WRITE transaction is active.
*
* @see session_get_trx_state
*
* @note The return value is valid only if either a router or a filter
* has declared that it needs RCAP_TYPE_TRANSACTION_TRACKING.
*
* @return True if an explicit READ WRITE transaction is active,
* false otherwise.
*/
@ -303,6 +330,8 @@ static inline bool session_trx_is_read_write(const SESSION* ses)
*
* Note also that by default autocommit is ON.
*
* @see session_get_trx_state
*
* @return True if autocommit has been set ON, false otherwise.
*/
static inline bool session_is_autocommit(const SESSION* ses)

View File

@ -142,7 +142,7 @@ session_alloc(SERVICE *service, DCB *client_dcb)
*/
session->state = SESSION_STATE_READY;
session->trx_state = SESSION_TRX_UNKNOWN;
session->trx_state = SESSION_TRX_INACTIVE;
session->autocommit = true;
/*
* Only create a router session if we are not the listening
@ -1081,8 +1081,6 @@ const char* session_trx_state_to_string(session_trx_state_t state)
{
switch (state)
{
case SESSION_TRX_UNKNOWN:
return "SESSION_TRX_UNKNOWN";
case SESSION_TRX_INACTIVE:
return "SESSION_TRX_INACTIVE";
case SESSION_TRX_ACTIVE:

View File

@ -1439,25 +1439,28 @@ static int route_by_statement(SESSION* session, uint64_t capabilities, GWBUF** p
if (type & QUERY_TYPE_BEGIN_TRX)
{
session_trx_state_t trx_state;
if (type & QUERY_TYPE_WRITE)
{
trx_state = SESSION_TRX_READ_WRITE;
}
else if (type & QUERY_TYPE_READ)
{
trx_state = SESSION_TRX_READ_ONLY;
}
else
{
trx_state = SESSION_TRX_ACTIVE;
}
session_set_trx_state(session, trx_state);
if (type & QUERY_TYPE_DISABLE_AUTOCOMMIT)
{
session_set_autocommit(session, false);
session_set_trx_state(session, SESSION_TRX_INACTIVE);
}
else
{
session_trx_state_t trx_state;
if (type & QUERY_TYPE_WRITE)
{
trx_state = SESSION_TRX_READ_WRITE;
}
else if (type & QUERY_TYPE_READ)
{
trx_state = SESSION_TRX_READ_ONLY;
}
else
{
trx_state = SESSION_TRX_ACTIVE;
}
session_set_trx_state(session, trx_state);
}
}
else if ((type & QUERY_TYPE_COMMIT) || (type & QUERY_TYPE_ROLLBACK))