diff options
Diffstat (limited to 'sql/transaction.cc')
-rw-r--r-- | sql/transaction.cc | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/sql/transaction.cc b/sql/transaction.cc index 22e3ad7f87c..d6ef160206b 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -738,7 +738,7 @@ bool trans_xa_start(THD *thd) thd->transaction.xid_state.xa_state= XA_ACTIVE; thd->transaction.xid_state.rm_error= 0; thd->transaction.xid_state.xid.set(thd->lex->xid); - if (xid_cache_insert(&thd->transaction.xid_state)) + if (xid_cache_insert(thd, &thd->transaction.xid_state)) { thd->transaction.xid_state.xa_state= XA_NOTR; thd->transaction.xid_state.xid.null(); @@ -801,7 +801,7 @@ bool trans_xa_prepare(THD *thd) my_error(ER_XAER_NOTA, MYF(0)); else if (ha_prepare(thd)) { - xid_cache_delete(&thd->transaction.xid_state); + xid_cache_delete(thd, &thd->transaction.xid_state); thd->transaction.xid_state.xa_state= XA_NOTR; my_error(ER_XA_RBROLLBACK, MYF(0)); } @@ -830,6 +830,11 @@ bool trans_xa_commit(THD *thd) if (!thd->transaction.xid_state.xid.eq(thd->lex->xid)) { + if (thd->fix_xid_hash_pins()) + { + my_error(ER_OUT_OF_RESOURCES, MYF(0)); + DBUG_RETURN(TRUE); + } /* xid_state.in_thd is always true beside of xa recovery procedure. Note, that there is no race condition here between xid_cache_search @@ -840,7 +845,7 @@ bool trans_xa_commit(THD *thd) xa_cache_insert(XID, xa_states), which is called before starting client connections, and thus is always single-threaded. */ - XID_STATE *xs= xid_cache_search(thd->lex->xid); + XID_STATE *xs= xid_cache_search(thd, thd->lex->xid); res= !xs || xs->in_thd; if (res) my_error(ER_XAER_NOTA, MYF(0)); @@ -848,7 +853,7 @@ bool trans_xa_commit(THD *thd) { res= xa_trans_rolled_back(xs); ha_commit_or_rollback_by_xid(thd->lex->xid, !res); - xid_cache_delete(xs); + xid_cache_delete(thd, xs); } DBUG_RETURN(res); } @@ -911,7 +916,7 @@ bool trans_xa_commit(THD *thd) thd->server_status&= ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); - xid_cache_delete(&thd->transaction.xid_state); + xid_cache_delete(thd, &thd->transaction.xid_state); thd->transaction.xid_state.xa_state= XA_NOTR; DBUG_RETURN(res); @@ -935,14 +940,20 @@ bool trans_xa_rollback(THD *thd) if (!thd->transaction.xid_state.xid.eq(thd->lex->xid)) { - XID_STATE *xs= xid_cache_search(thd->lex->xid); + if (thd->fix_xid_hash_pins()) + { + my_error(ER_OUT_OF_RESOURCES, MYF(0)); + DBUG_RETURN(TRUE); + } + + XID_STATE *xs= xid_cache_search(thd, thd->lex->xid); if (!xs || xs->in_thd) my_error(ER_XAER_NOTA, MYF(0)); else { xa_trans_rolled_back(xs); ha_commit_or_rollback_by_xid(thd->lex->xid, 0); - xid_cache_delete(xs); + xid_cache_delete(thd, xs); } DBUG_RETURN(thd->get_stmt_da()->is_error()); } @@ -961,7 +972,7 @@ bool trans_xa_rollback(THD *thd) thd->server_status&= ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); - xid_cache_delete(&thd->transaction.xid_state); + xid_cache_delete(thd, &thd->transaction.xid_state); thd->transaction.xid_state.xa_state= XA_NOTR; DBUG_RETURN(res); |