diff --git a/include/maxscale/session.h b/include/maxscale/session.h index 9c5f32f48..5cdd6237d 100644 --- a/include/maxscale/session.h +++ b/include/maxscale/session.h @@ -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. * diff --git a/server/core/session.c b/server/core/session.c index d1b2e0548..8059d9ff2 100644 --- a/server/core/session.c +++ b/server/core/session.c @@ -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); diff --git a/server/modules/protocol/MySQL/MySQLClient/mysql_client.c b/server/modules/protocol/MySQL/MySQLClient/mysql_client.c index 6e4acc368..a4a106a1e 100644 --- a/server/modules/protocol/MySQL/MySQLClient/mysql_client.c +++ b/server/modules/protocol/MySQL/MySQLClient/mysql_client.c @@ -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) {