[master] fix xa-tx free-route check alive
This commit is contained in:
@ -337,29 +337,33 @@ int ObSqlTransControl::kill_tx(ObSQLSessionInfo *session, int cause)
|
||||
auto session_id = session->get_sessid();
|
||||
LOG_INFO("begin to kill tx", K(cause), K(session_id), KPC(session));
|
||||
int ret = OB_SUCCESS;
|
||||
if (session->is_in_transaction() && !session->is_txn_free_route_temp()) {
|
||||
if (session->is_in_transaction()) {
|
||||
transaction::ObTxDesc *tx_desc = session->get_tx_desc();
|
||||
auto tx_tenant_id = tx_desc->get_tenant_id();
|
||||
const ObTransID tx_id = tx_desc->get_tx_id();
|
||||
auto tx_free_route_tmp = session->is_txn_free_route_temp();
|
||||
MTL_SWITCH(tx_tenant_id) {
|
||||
if (tx_desc->is_xa_trans()) {
|
||||
if (tx_free_route_tmp) {
|
||||
// if XA-txn is on this server, we have acquired its ref, release ref
|
||||
// and disassocate with session
|
||||
if (tx_desc->is_xa_trans() && tx_desc->get_addr() == GCONF.self_addr_) {
|
||||
auto txs = MTL(transaction::ObTransService*);
|
||||
CK (OB_NOT_NULL(txs));
|
||||
OZ (txs->release_tx_ref(*tx_desc));
|
||||
OX (session->get_tx_desc() = NULL);
|
||||
}
|
||||
} else if (tx_desc->is_xa_trans()) {
|
||||
const transaction::ObXATransID xid = session->get_xid();
|
||||
const transaction::ObGlobalTxType global_tx_type = tx_desc->get_global_tx_type(xid);
|
||||
auto xas = MTL(transaction::ObXAService *);
|
||||
CK (OB_NOT_NULL(xas));
|
||||
if (transaction::ObGlobalTxType::XA_TRANS == global_tx_type) {
|
||||
if (OB_FAIL(MTL(transaction::ObXAService *)->handle_terminate_for_xa_branch(
|
||||
session->get_xid(), tx_desc, session->get_xa_end_timeout_seconds()))) {
|
||||
LOG_WARN("rollback xa trans fail", K(ret), K(xid), K(global_tx_type), K(session_id),
|
||||
K(tx_id));
|
||||
} else {
|
||||
OZ (xas->handle_terminate_for_xa_branch(session->get_xid(), tx_desc, session->get_xa_end_timeout_seconds()),
|
||||
xid, global_tx_type, session_id, tx_id);
|
||||
// currently, tx_desc is NULL
|
||||
}
|
||||
} else if (transaction::ObGlobalTxType::DBLINK_TRANS == global_tx_type) {
|
||||
if (OB_FAIL(MTL(transaction::ObXAService *)->rollback_for_dblink_trans(tx_desc))) {
|
||||
LOG_WARN("fail to rollback for dblink trans", K(ret), K(xid), K(global_tx_type),
|
||||
K(tx_id));
|
||||
} else {
|
||||
OZ (xas->rollback_for_dblink_trans(tx_desc), ret, xid, global_tx_type, tx_id);
|
||||
// currently, tx_desc is NULL
|
||||
}
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected global trans type", K(ret), K(xid), K(global_tx_type), K(tx_id));
|
||||
@ -367,12 +371,11 @@ int ObSqlTransControl::kill_tx(ObSQLSessionInfo *session, int cause)
|
||||
session->get_tx_desc() = NULL;
|
||||
} else {
|
||||
transaction::ObTransService *txs = NULL;
|
||||
CK(OB_NOT_NULL(txs = MTL_WITH_CHECK_TENANT(transaction::ObTransService*,
|
||||
tx_tenant_id)));
|
||||
CK(OB_NOT_NULL(txs = MTL_WITH_CHECK_TENANT(transaction::ObTransService*, tx_tenant_id)));
|
||||
OZ(txs->abort_tx(*tx_desc, cause), *session, tx_desc->get_tx_id());
|
||||
}
|
||||
// NOTE that the tx_desc is set to NULL in xa case, DO NOT print anything in tx_desc
|
||||
LOG_INFO("kill tx done", K(ret), K(cause), K(session_id), K(tx_id));
|
||||
LOG_INFO("kill tx done", K(ret), K(cause), K(session_id), K(tx_id), K(tx_free_route_tmp));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -1774,7 +1774,9 @@ int ObTransService::sql_stmt_start_hook(const ObXATransID &xid, ObTxDesc &tx, co
|
||||
TRANS_LOG(WARN, "need rollback", K(ret), K(global_tx_type), K(xid));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (tx.is_xa_tightly_couple()) {
|
||||
// loosely couple mode txn-route use session_id to detect xa-start node's alive
|
||||
// so, can not overwrite session_id
|
||||
tx.set_sessid(session_id);
|
||||
}
|
||||
if (OB_FAIL(ret) && registed) {
|
||||
|
@ -80,6 +80,7 @@ int ObTxFreeRouteCheckAliveRespP::kill_session_()
|
||||
sql::ObSQLSessionInfo *session = NULL;
|
||||
if (OB_SUCC(guard.get_session(session))) {
|
||||
if (session->get_is_in_retry()) {
|
||||
// TODO: only kill session when it is idle
|
||||
} else if (OB_FAIL(GCTX.session_mgr_->kill_session(*session))) {
|
||||
TRANS_LOG(WARN, "kill session fail", K(ret));
|
||||
}
|
||||
@ -95,9 +96,10 @@ int ObTxFreeRouteCheckAliveRespP::release_session_tx_()
|
||||
if (OB_FAIL(guard.get_session(session))) {
|
||||
} else if (session->get_is_in_retry()) {
|
||||
// skip quit txn if session in Query Retry
|
||||
} else if (OB_FAIL(session->try_lock_query())) {
|
||||
} else if (OB_FAIL(session->try_lock_thread_data())) {
|
||||
session->unlock_query();
|
||||
} else {
|
||||
sql::ObSQLSessionInfo::LockGuard query_lock_guard(session->get_query_lock());
|
||||
sql::ObSQLSessionInfo::LockGuard data_lock_guard(session->get_thread_data_lock());
|
||||
auto &ctx = session->get_txn_free_route_ctx();
|
||||
auto &tx_desc = session->get_tx_desc();
|
||||
if (ctx.get_local_version() != arg_.request_id_) {
|
||||
@ -124,6 +126,8 @@ int ObTxFreeRouteCheckAliveRespP::release_session_tx_()
|
||||
TRANS_LOG(INFO, "[txn free route] release tx success");
|
||||
}
|
||||
}
|
||||
session->unlock_query();
|
||||
session->unlock_thread_data();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
Reference in New Issue
Block a user