summaryrefslogtreecommitdiff
path: root/sql/transaction.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/transaction.cc')
-rw-r--r--sql/transaction.cc95
1 files changed, 87 insertions, 8 deletions
diff --git a/sql/transaction.cc b/sql/transaction.cc
index 8b188709ce6..9bacfb81bba 100644
--- a/sql/transaction.cc
+++ b/sql/transaction.cc
@@ -25,6 +25,44 @@
#include "debug_sync.h" // DEBUG_SYNC
#include "sql_acl.h"
+
+#ifndef EMBEDDED_LIBRARY
+/**
+ Helper: Tell tracker (if any) that transaction ended.
+*/
+static void trans_track_end_trx(THD *thd)
+{
+ if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
+ {
+ ((Transaction_state_tracker *)
+ thd->session_tracker.get_tracker(TRANSACTION_INFO_TRACKER))->end_trx(thd);
+ }
+}
+#else
+#define trans_track_end_trx(A) do{}while(0)
+#endif //EMBEDDED_LIBRARY
+
+
+/**
+ Helper: transaction ended, SET TRANSACTION one-shot variables
+ revert to session values. Let the transaction state tracker know.
+*/
+void trans_reset_one_shot_chistics(THD *thd)
+{
+#ifndef EMBEDDED_LIBRARY
+ if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
+ {
+ Transaction_state_tracker *tst= (Transaction_state_tracker *)
+ thd->session_tracker.get_tracker(TRANSACTION_INFO_TRACKER);
+
+ tst->set_read_flags(thd, TX_READ_INHERIT);
+ tst->set_isol_level(thd, TX_ISOL_INHERIT);
+ }
+#endif //EMBEDDED_LIBRARY
+ thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
+ thd->tx_read_only= thd->variables.tx_read_only;
+}
+
/* Conditions under which the transaction state must not change. */
static bool trans_check(THD *thd)
{
@@ -125,11 +163,20 @@ static bool xa_trans_force_rollback(THD *thd)
bool trans_begin(THD *thd, uint flags)
{
int res= FALSE;
+#ifndef EMBEDDED_LIBRARY
+ Transaction_state_tracker *tst= NULL;
+#endif //EMBEDDED_LIBRARY
DBUG_ENTER("trans_begin");
if (trans_check(thd))
DBUG_RETURN(TRUE);
+#ifndef EMBEDDED_LIBRARY
+ if (thd->variables.session_track_transaction_info > TX_TRACK_NONE)
+ tst= (Transaction_state_tracker *)
+ thd->session_tracker.get_tracker(TRANSACTION_INFO_TRACKER);
+#endif //EMBEDDED_LIBRARY
+
thd->locked_tables_list.unlock_locked_tables(thd);
DBUG_ASSERT(!thd->locked_tables_mode);
@@ -172,7 +219,13 @@ bool trans_begin(THD *thd, uint flags)
DBUG_ASSERT(!((flags & MYSQL_START_TRANS_OPT_READ_ONLY) &&
(flags & MYSQL_START_TRANS_OPT_READ_WRITE)));
if (flags & MYSQL_START_TRANS_OPT_READ_ONLY)
+ {
thd->tx_read_only= true;
+#ifndef EMBEDDED_LIBRARY
+ if (tst)
+ tst->set_read_flags(thd, TX_READ_ONLY);
+#endif //EMBEDDED_LIBRARY
+ }
else if (flags & MYSQL_START_TRANS_OPT_READ_WRITE)
{
/*
@@ -189,6 +242,14 @@ bool trans_begin(THD *thd, uint flags)
DBUG_RETURN(true);
}
thd->tx_read_only= false;
+ /*
+ This flags that tx_read_only was set explicitly, rather than
+ just from the session's default.
+ */
+#ifndef EMBEDDED_LIBRARY
+ if (tst)
+ tst->set_read_flags(thd, TX_READ_WRITE);
+#endif //EMBEDDED_LIBRARY
}
#ifdef WITH_WSREP
@@ -203,9 +264,20 @@ bool trans_begin(THD *thd, uint flags)
thd->server_status|= SERVER_STATUS_IN_TRANS_READONLY;
DBUG_PRINT("info", ("setting SERVER_STATUS_IN_TRANS"));
+#ifndef EMBEDDED_LIBRARY
+ if (tst)
+ tst->add_trx_state(thd, TX_EXPLICIT);
+#endif //EMBEDDED_LIBRARY
+
/* ha_start_consistent_snapshot() relies on OPTION_BEGIN flag set. */
if (flags & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
+ {
+#ifndef EMBEDDED_LIBRARY
+ if (tst)
+ tst->add_trx_state(thd, TX_WITH_SNAPSHOT);
+#endif //EMBEDDED_LIBRARY
res= ha_start_consistent_snapshot(thd);
+ }
DBUG_RETURN(MY_TEST(res));
}
@@ -255,6 +327,8 @@ bool trans_commit(THD *thd)
thd->transaction.all.m_unsafe_rollback_flags&= ~THD_TRANS::DID_WAIT;
thd->lex->start_transaction_opt= 0;
+ trans_track_end_trx(thd);
+
DBUG_RETURN(MY_TEST(res));
}
@@ -308,8 +382,9 @@ bool trans_commit_implicit(THD *thd)
@@session.completion_type since it's documented
to not have any effect on implicit commit.
*/
- thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
- thd->tx_read_only= thd->variables.tx_read_only;
+ trans_reset_one_shot_chistics(thd);
+
+ trans_track_end_trx(thd);
DBUG_RETURN(res);
}
@@ -349,6 +424,8 @@ bool trans_rollback(THD *thd)
thd->transaction.all.m_unsafe_rollback_flags&= ~THD_TRANS::DID_WAIT;
thd->lex->start_transaction_opt= 0;
+ trans_track_end_trx(thd);
+
DBUG_RETURN(MY_TEST(res));
}
@@ -396,6 +473,8 @@ bool trans_rollback_implicit(THD *thd)
/* Rollback should clear transaction_rollback_request flag. */
DBUG_ASSERT(! thd->transaction_rollback_request);
+ trans_track_end_trx(thd);
+
DBUG_RETURN(MY_TEST(res));
}
@@ -434,8 +513,7 @@ bool trans_commit_stmt(THD *thd)
res= ha_commit_trans(thd, FALSE);
if (! thd->in_active_multi_stmt_transaction())
{
- thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
- thd->tx_read_only= thd->variables.tx_read_only;
+ trans_reset_one_shot_chistics(thd);
if (WSREP_ON)
wsrep_post_commit(thd, FALSE);
}
@@ -487,10 +565,7 @@ bool trans_rollback_stmt(THD *thd)
wsrep_register_hton(thd, FALSE);
ha_rollback_trans(thd, FALSE);
if (! thd->in_active_multi_stmt_transaction())
- {
- thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
- thd->tx_read_only= thd->variables.tx_read_only;
- }
+ trans_reset_one_shot_chistics(thd);
}
(void) RUN_HOOK(transaction, after_rollback, (thd, FALSE));
@@ -912,6 +987,8 @@ bool trans_xa_commit(THD *thd)
xid_cache_delete(thd, &thd->transaction.xid_state);
thd->transaction.xid_state.xa_state= XA_NOTR;
+ trans_track_end_trx(thd);
+
DBUG_RETURN(res);
}
@@ -968,5 +1045,7 @@ bool trans_xa_rollback(THD *thd)
xid_cache_delete(thd, &thd->transaction.xid_state);
thd->transaction.xid_state.xa_state= XA_NOTR;
+ trans_track_end_trx(thd);
+
DBUG_RETURN(res);
}