only reset tx active_scn to enable recgnize first stmt retry
This commit is contained in:
parent
cfe4eeda1c
commit
9474ff14d4
@ -1098,7 +1098,9 @@ int ObSqlTransControl::end_stmt(ObExecContext &exec_ctx, const bool rollback)
|
||||
#else
|
||||
if (OB_FAIL(ret) || rollback) { print_log = true; }
|
||||
#endif
|
||||
if (print_log && OB_NOT_NULL(session)) {
|
||||
if (print_log
|
||||
&& OB_NOT_NULL(session)
|
||||
&& OB_TRY_LOCK_ROW_CONFLICT != exec_ctx.get_errcode()) {
|
||||
LOG_INFO("end stmt", K(ret),
|
||||
"plain_select", is_plain_select,
|
||||
"stmt_type", stmt_type,
|
||||
|
@ -680,6 +680,15 @@ int ObTxDesc::update_part_(ObTxPart &a, const bool append)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ObTxDesc::State::IMPLICIT_ACTIVE == state_ && !active_scn_.is_valid()) {
|
||||
/*
|
||||
* it is a first stmt's retry, we should set active scn
|
||||
* to enable recognizing it is first stmt
|
||||
*/
|
||||
active_scn_ = get_tx_seq();
|
||||
}
|
||||
|
||||
if (!hit) {
|
||||
if (append) {
|
||||
a.last_touch_ts_ = exec_info_reap_ts_ + 1;
|
||||
@ -755,15 +764,8 @@ void ObTxDesc::implicit_start_tx_()
|
||||
{
|
||||
if (parts_.count() > 0 && state_ == ObTxDesc::State::IDLE) {
|
||||
state_ = ObTxDesc::State::IMPLICIT_ACTIVE;
|
||||
if (expire_ts_ == INT64_MAX ) {
|
||||
/*
|
||||
* To calculate transaction's execution time
|
||||
* and determine whether transaction has timeout
|
||||
* just set active_ts and expire_ts on stmt's first execution
|
||||
*/
|
||||
active_ts_ = ObClockGenerator::getClock();
|
||||
expire_ts_ = active_ts_ + timeout_us_;
|
||||
}
|
||||
active_ts_ = ObClockGenerator::getClock();
|
||||
expire_ts_ = active_ts_ + timeout_us_;
|
||||
active_scn_ = get_tx_seq();
|
||||
state_change_flags_.mark_all();
|
||||
}
|
||||
|
@ -1136,7 +1136,7 @@ int ObTransService::rollback_to_global_implicit_savepoint_(ObTxDesc &tx,
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t start_ts = ObTimeUtility::current_time();
|
||||
tx.inc_op_sn();
|
||||
bool reset_tx = false, normal_rollback = false, reset_tx_state = false;
|
||||
bool reset_tx = false, normal_rollback = false, reset_active_scn = false;
|
||||
// merge extra touched ls
|
||||
if (OB_NOT_NULL(extra_touched_ls) && !extra_touched_ls->empty()) {
|
||||
if (OB_FAIL(tx.update_parts(*extra_touched_ls))) {
|
||||
@ -1164,13 +1164,13 @@ int ObTransService::rollback_to_global_implicit_savepoint_(ObTxDesc &tx,
|
||||
&& tx.active_scn_ >= savepoint // rollback all dirty state
|
||||
&& !tx.has_extra_state_()) { // hasn't explicit savepoint or serializable snapshot
|
||||
/*
|
||||
* if sql execute error code don't need reset(abort) tx but need rollback stmt and retry
|
||||
* if sql execute error code don't need reset(abort) tx but need retry
|
||||
* e.g. "lock conflict error"
|
||||
* to ensure next retry can still recognize it is first stmt in transaction
|
||||
* we should reset tx state
|
||||
* to ensure next retry can still recognize it is the first stmt in transaction
|
||||
* we should reset tx's acitve_scn
|
||||
*/
|
||||
reset_tx = true; // tx_need_reset_(exec_errcode);
|
||||
reset_tx_state = !reset_tx;
|
||||
reset_tx = tx_need_reset_(exec_errcode);
|
||||
reset_active_scn = !reset_tx;
|
||||
normal_rollback = !reset_tx;
|
||||
} else {
|
||||
normal_rollback = true;
|
||||
@ -1207,10 +1207,7 @@ int ObTransService::rollback_to_global_implicit_savepoint_(ObTxDesc &tx,
|
||||
tx.inc_op_sn();
|
||||
abort_tx_(tx, ObTxAbortCause::SAVEPOINT_ROLLBACK_FAIL);
|
||||
} else {
|
||||
if (reset_tx_state) {
|
||||
// first stmt retry need reset tx state
|
||||
tx.state_ = ObTxDesc::State::IDLE;
|
||||
tx.parts_.reset();
|
||||
if (reset_active_scn) {
|
||||
tx.active_scn_.reset();
|
||||
}
|
||||
/*
|
||||
|
@ -321,8 +321,7 @@ TEST_F(ObTestTx, rollback_savepoint_with_need_retry_error)
|
||||
ASSERT_TRUE(sp.is_valid());
|
||||
ASSERT_EQ(OB_SUCCESS, n1->write(tx, snapshot, 100, 200));
|
||||
ASSERT_EQ(OB_SUCCESS, n1->rollback_to_implicit_savepoint(tx, sp, n1->ts_after_ms(5), nullptr, OB_TRANSACTION_SET_VIOLATION));
|
||||
ASSERT_EQ(ObTxDesc::State::IDLE, tx.state_);
|
||||
ASSERT_EQ(0, tx.parts_.count());
|
||||
ASSERT_EQ(ObTxDesc::State::IMPLICIT_ACTIVE, tx.state_);
|
||||
ASSERT_EQ(ObTxSEQ::INVL(), tx.active_scn_);
|
||||
ASSERT_EQ(OB_SUCCESS, n1->rollback_to_implicit_savepoint(tx, sp, n1->ts_after_ms(5), nullptr));
|
||||
}
|
||||
@ -332,8 +331,7 @@ TEST_F(ObTestTx, rollback_savepoint_with_need_retry_error)
|
||||
ASSERT_TRUE(sp.is_valid());
|
||||
ASSERT_EQ(OB_SUCCESS, n1->write(tx, snapshot, 100, 200));
|
||||
ASSERT_EQ(OB_SUCCESS, n1->rollback_to_implicit_savepoint(tx, sp, n1->ts_after_ms(5), nullptr, OB_TRY_LOCK_ROW_CONFLICT));
|
||||
ASSERT_EQ(ObTxDesc::State::IDLE, tx.state_);
|
||||
ASSERT_EQ(0, tx.parts_.count());
|
||||
ASSERT_EQ(ObTxDesc::State::IMPLICIT_ACTIVE, tx.state_);
|
||||
ASSERT_EQ(ObTxSEQ::INVL(), tx.active_scn_);
|
||||
ASSERT_EQ(OB_SUCCESS, n1->rollback_to_implicit_savepoint(tx, sp, n1->ts_after_ms(5), nullptr));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user