MDEV-14609 XA Transction unable to ROLLBACK TO SAVEPOINT
The function trans_rollback_to_savepoint(), unlike trans_savepoint(), did not allow xa_state=XA_ACTIVE, so an attempt to do ROLLBCK TO SAVEPOINT inside an XA transaction incorrectly returned an error "...command cannot be executed ... in the ACTIVE state...". Partially merging a MySQL patch: 7fb5c47390311d9b1b5367f97cb8fedd4102dd05 This is WL#7193 (Decouple THD and st_transactions)... The currently merged part includes these changes: - Introducing st_xid_state::check_has_uncommitted_xa() - Reusing it in both trans_rollback_to_savepoint() and trans_savepoint(), so now both allow XA_ACTIVE.
This commit is contained in:
parent
5fe1d7d076
commit
88a9b23396
@ -200,6 +200,17 @@ a
|
|||||||
1
|
1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-14609 XA Transction unable to ROLLBACK TO SAVEPOINT
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (c1 INT) ENGINE=INNODB;
|
||||||
|
XA START 'xa1';
|
||||||
|
SAVEPOINT savepoint1;
|
||||||
|
INSERT INTO t1 (c1) VALUES (1),(2),(3),(4);
|
||||||
|
ROLLBACK TO SAVEPOINT savepoint1;
|
||||||
|
XA END 'xa1';
|
||||||
|
XA ROLLBACK 'xa1';
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# Bug#12352846 - TRANS_XA_START(THD*):
|
# Bug#12352846 - TRANS_XA_START(THD*):
|
||||||
# ASSERTION THD->TRANSACTION.XID_STATE.XID.IS_NULL()
|
# ASSERTION THD->TRANSACTION.XID_STATE.XID.IS_NULL()
|
||||||
# FAILED
|
# FAILED
|
||||||
|
@ -327,6 +327,20 @@ SELECT * FROM t1;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-14609 XA Transction unable to ROLLBACK TO SAVEPOINT
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (c1 INT) ENGINE=INNODB;
|
||||||
|
XA START 'xa1';
|
||||||
|
SAVEPOINT savepoint1;
|
||||||
|
INSERT INTO t1 (c1) VALUES (1),(2),(3),(4);
|
||||||
|
ROLLBACK TO SAVEPOINT savepoint1;
|
||||||
|
XA END 'xa1';
|
||||||
|
XA ROLLBACK 'xa1';
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Bug#12352846 - TRANS_XA_START(THD*):
|
--echo # Bug#12352846 - TRANS_XA_START(THD*):
|
||||||
--echo # ASSERTION THD->TRANSACTION.XID_STATE.XID.IS_NULL()
|
--echo # ASSERTION THD->TRANSACTION.XID_STATE.XID.IS_NULL()
|
||||||
|
@ -991,6 +991,30 @@ typedef struct st_xid_state {
|
|||||||
bool in_thd;
|
bool in_thd;
|
||||||
/* Error reported by the Resource Manager (RM) to the Transaction Manager. */
|
/* Error reported by the Resource Manager (RM) to the Transaction Manager. */
|
||||||
uint rm_error;
|
uint rm_error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check that XA transaction has an uncommitted work. Report an error
|
||||||
|
to the user in case when there is an uncommitted work for XA transaction.
|
||||||
|
|
||||||
|
@return result of check
|
||||||
|
@retval false XA transaction is NOT in state IDLE, PREPARED
|
||||||
|
or ROLLBACK_ONLY.
|
||||||
|
@retval true XA transaction is in state IDLE or PREPARED
|
||||||
|
or ROLLBACK_ONLY.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool check_has_uncommitted_xa() const
|
||||||
|
{
|
||||||
|
if (xa_state == XA_IDLE ||
|
||||||
|
xa_state == XA_PREPARED ||
|
||||||
|
xa_state == XA_ROLLBACK_ONLY)
|
||||||
|
{
|
||||||
|
my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} XID_STATE;
|
} XID_STATE;
|
||||||
|
|
||||||
extern mysql_mutex_t LOCK_xid_cache;
|
extern mysql_mutex_t LOCK_xid_cache;
|
||||||
|
@ -433,12 +433,8 @@ bool trans_savepoint(THD *thd, LEX_STRING name)
|
|||||||
!opt_using_transactions)
|
!opt_using_transactions)
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
|
|
||||||
enum xa_states xa_state= thd->transaction.xid_state.xa_state;
|
if (thd->transaction.xid_state.check_has_uncommitted_xa())
|
||||||
if (xa_state != XA_NOTR && xa_state != XA_ACTIVE)
|
|
||||||
{
|
|
||||||
my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]);
|
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
|
||||||
|
|
||||||
sv= find_savepoint(thd, name);
|
sv= find_savepoint(thd, name);
|
||||||
|
|
||||||
@ -513,12 +509,8 @@ bool trans_rollback_to_savepoint(THD *thd, LEX_STRING name)
|
|||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum xa_states xa_state= thd->transaction.xid_state.xa_state;
|
if (thd->transaction.xid_state.check_has_uncommitted_xa())
|
||||||
if (xa_state != XA_NOTR)
|
|
||||||
{
|
|
||||||
my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]);
|
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
|
||||||
|
|
||||||
if (ha_rollback_to_savepoint(thd, sv))
|
if (ha_rollback_to_savepoint(thd, sv))
|
||||||
res= TRUE;
|
res= TRUE;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user