Track transaction end as well as start

The COMMIT and ROLLBACK are now detected. This can be used to route the
trailing end of a transaction to a specific server.
This commit is contained in:
Markus Mäkelä 2017-01-24 11:09:58 +02:00
parent 6bcf0b1fd6
commit 81be935fa9
3 changed files with 30 additions and 6 deletions

View File

@ -48,10 +48,11 @@ typedef enum
typedef enum
{
SESSION_TRX_INACTIVE_BIT = 1, /* 0b0001 */
SESSION_TRX_ACTIVE_BIT = 2, /* 0b0010 */
SESSION_TRX_READ_ONLY_BIT = 4, /* 0b0100 */
SESSION_TRX_READ_WRITE_BIT = 8, /* 0b1000 */
SESSION_TRX_INACTIVE_BIT = 0x01, /* 0b00001 */
SESSION_TRX_ACTIVE_BIT = 0x02, /* 0b00010 */
SESSION_TRX_READ_ONLY_BIT = 0x04, /* 0b00100 */
SESSION_TRX_READ_WRITE_BIT = 0x08, /* 0b01000 */
SESSION_TRX_ENDING_BIT = 0x10, /* 0b10000*/
} session_trx_state_bit_t;
typedef enum
@ -63,7 +64,8 @@ typedef enum
/*< An explicit READ ONLY transaction is active. */
SESSION_TRX_READ_ONLY = (SESSION_TRX_ACTIVE_BIT | SESSION_TRX_READ_ONLY_BIT),
/*< An explicit READ WRITE transaction is active. */
SESSION_TRX_READ_WRITE = (SESSION_TRX_ACTIVE_BIT | SESSION_TRX_READ_WRITE_BIT)
SESSION_TRX_READ_WRITE = (SESSION_TRX_ACTIVE_BIT | SESSION_TRX_READ_WRITE_BIT),
SESSION_TRX_ENDING = SESSION_TRX_ENDING_BIT,
} mxs_session_trx_state_t;
/**
@ -245,6 +247,21 @@ static inline bool session_trx_is_read_write(const MXS_SESSION* ses)
return ses->trx_state == SESSION_TRX_READ_WRITE;
}
/**
* Tells whether a transaction is ending.
*
* @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 that was active is ending either via COMMIT or ROLLBACK.
*/
static inline bool session_trx_is_ending(const MXS_SESSION* ses)
{
return ses->trx_state == SESSION_TRX_ENDING;
}
/**
* Tells whether autocommit is ON or not.
*

View File

@ -897,6 +897,8 @@ const char* session_trx_state_to_string(mxs_session_trx_state_t state)
return "SESSION_TRX_READ_ONLY";
case SESSION_TRX_READ_WRITE:
return "SESSION_TRX_READ_WRITE";
case SESSION_TRX_ENDING:
return "SESSION_TRX_ENDING";
}
MXS_ERROR("Unknown session_trx_state_t value: %d", (int)state);

View File

@ -1483,6 +1483,11 @@ static int route_by_statement(MXS_SESSION* session, uint64_t capabilities, GWBUF
{
uint8_t *data = GWBUF_DATA(packetbuf);
if (session_trx_is_ending(session))
{
session_set_trx_state(session, SESSION_TRX_INACTIVE);
}
if (MYSQL_GET_COMMAND(data) == MYSQL_COM_QUERY)
{
uint32_t type = qc_get_type_mask(packetbuf);
@ -1515,7 +1520,7 @@ static int route_by_statement(MXS_SESSION* session, uint64_t capabilities, GWBUF
}
else if ((type & QUERY_TYPE_COMMIT) || (type & QUERY_TYPE_ROLLBACK))
{
session_set_trx_state(session, SESSION_TRX_INACTIVE);
session_set_trx_state(session, SESSION_TRX_ENDING);
if (type & QUERY_TYPE_ENABLE_AUTOCOMMIT)
{