Track session autocommit state

This tracks only what is explicitly set. That is, if autocommit
has been set true then, even if a transaction is started, autocommit
will not be set false.

That is, a user of the session autocommit and transaction states
need to be aware of their semantics. If a transaction is active,
then the state of autocommit is irrelevant.
This commit is contained in:
Johan Wikman 2016-10-21 13:08:18 +03:00
parent 5cc436c37c
commit 693d8dcbb4
3 changed files with 45 additions and 0 deletions

View File

@ -181,6 +181,7 @@ typedef struct session
int refcount; /*< Reference count on the session */
bool ses_is_child; /*< this is a child session */
session_trx_state_t trx_state; /*< The current transaction state. */
bool autocommit; /*< Whether autocommit is on. */
skygw_chk_t ses_chk_tail;
} SESSION;
@ -289,6 +290,41 @@ static inline bool session_trx_is_read_write(const SESSION* ses)
return ses->trx_state == SESSION_TRX_READ_WRITE;
}
/**
* Tells whether autocommit is ON or not.
*
* Note that the returned value effectively only tells the last value
* of the statement "set autocommit=...".
*
* That is, if the statement "set autocommit=1" has been executed, then
* even if a transaction has been started, which implicitly will cause
* autocommit to be set to 0 for the duration of the transaction, this
* function will still return true.
*
* Note also that by default autocommit is ON.
*
* @return True if autocommit has been set ON, false otherwise.
*/
static inline bool session_is_autocommit(const SESSION* ses)
{
return ses->autocommit;
}
/**
* Sets the autocommit state of the session.
*
* NOTE: Only the protocol object may call this.
*
* @param enable True if autocommit is enabled, false otherwise.
* @return The previous state.
*/
static inline bool session_set_autocommit(SESSION* ses, bool autocommit)
{
bool prev_autocommit = ses->autocommit;
ses->autocommit = autocommit;
return prev_autocommit;
}
MXS_END_DECLS
#endif

View File

@ -143,6 +143,7 @@ session_alloc(SERVICE *service, DCB *client_dcb)
session->state = SESSION_STATE_READY;
session->trx_state = SESSION_TRX_UNKNOWN;
session->autocommit = true;
/*
* Only create a router session if we are not the listening
* DCB or an internal DCB. Creating a router session may create a connection to a

View File

@ -916,6 +916,14 @@ gw_read_finish_processing(DCB *dcb, GWBUF *read_buffer, uint64_t capabilities)
{
session_set_trx_state(ses, SESSION_TRX_INACTIVE);
}
else if (type & QUERY_TYPE_ENABLE_AUTOCOMMIT)
{
session_set_autocommit(ses, true);
}
else if (type & QUERY_TYPE_DISABLE_AUTOCOMMIT)
{
session_set_autocommit(ses, false);
}
/**
* Feed each statement completely and separately