fix set transaction characters
This commit is contained in:
parent
729ab79348
commit
989a8f3547
@ -1026,7 +1026,10 @@ int ObVariableSetExecutor::process_session_autocommit_hook(ObExecContext &exec_c
|
||||
}
|
||||
// skip commit txn if this is txn free route temporary node
|
||||
} else if (false == orig_ac && true == in_trans && 1 == autocommit && !my_session->is_txn_free_route_temp()) {
|
||||
if (OB_FAIL(ObSqlTransControl::implicit_end_trans(exec_ctx, false))) {
|
||||
// set autocommit = 1 won't clear next scope transaction settings:
|
||||
// `set transaction read only`
|
||||
// `set transaction isolation level`
|
||||
if (OB_FAIL(ObSqlTransControl::implicit_end_trans(exec_ctx, false, NULL, false))) {
|
||||
LOG_WARN("fail implicit commit trans", K(ret));
|
||||
}
|
||||
} else {
|
||||
|
@ -277,9 +277,16 @@ int ObResultSet::on_cmd_execute()
|
||||
}
|
||||
get_exec_context().set_need_disconnect(false);
|
||||
} else {
|
||||
// commit current open transaction, synchronously
|
||||
if (OB_FAIL(ObSqlTransControl::implicit_end_trans(get_exec_context(), false))) {
|
||||
SQL_ENG_LOG(WARN, "fail end implicit trans on cmd execute", K(ret));
|
||||
// implicit end transaction and start transaction will not clear next scope transaction settings by:
|
||||
// a. set by `set transaction read only`
|
||||
// b. set by `set transaction isolation level XXX`
|
||||
const int cmd_type = cmd_->get_cmd_type();
|
||||
bool keep_trans_variable = (cmd_type == stmt::T_START_TRANS);
|
||||
if (OB_FAIL(ObSqlTransControl::implicit_end_trans(get_exec_context(), false, NULL, !keep_trans_variable))) {
|
||||
LOG_WARN("fail end implicit trans on cmd execute", K(ret));
|
||||
} else if (my_session_.need_recheck_txn_readonly() && my_session_.get_tx_read_only()) {
|
||||
ret = OB_ERR_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION;
|
||||
LOG_WARN("cmd can not execute because txn is read only", K(ret), K(cmd_type));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -967,7 +974,7 @@ OB_INLINE int ObResultSet::auto_end_plan_trans(ObPhysicalPlan& plan,
|
||||
K(in_trans), K(ac), K(explicit_trans),
|
||||
K(is_async_end_trans_submitted()));
|
||||
// explicit start trans will disable auto-commit
|
||||
if (!explicit_trans && ac) {
|
||||
if (!explicit_trans && ac && plan.is_need_trans()) {
|
||||
ObPhysicalPlanCtx *plan_ctx = NULL;
|
||||
if (OB_ISNULL(plan_ctx = get_exec_context().get_physical_plan_ctx())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
@ -1027,7 +1034,7 @@ OB_INLINE int ObResultSet::auto_end_plan_trans(ObPhysicalPlan& plan,
|
||||
}
|
||||
NG_TRACE(auto_end_plan_end);
|
||||
LOG_TRACE("auto_end_plan_trans.end", K(ret),
|
||||
K(in_trans), K(ac), K(explicit_trans),
|
||||
K(in_trans), K(ac), K(explicit_trans), K(plan.is_need_trans()),
|
||||
K(is_rollback), K(async),
|
||||
K(is_async_end_trans_submitted()));
|
||||
return ret;
|
||||
|
@ -198,7 +198,8 @@ int ObSqlTransControl::explicit_start_trans(ObExecContext &ctx, const bool read_
|
||||
|
||||
int ObSqlTransControl::implicit_end_trans(ObExecContext &exec_ctx,
|
||||
const bool is_rollback,
|
||||
ObEndTransAsyncCallback *callback)
|
||||
ObEndTransAsyncCallback *callback,
|
||||
bool reset_trans_variable)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
#ifndef NDEBUG
|
||||
@ -210,7 +211,7 @@ int ObSqlTransControl::implicit_end_trans(ObExecContext &exec_ctx,
|
||||
OX (tx_id = session->get_tx_id().get_id());
|
||||
CHECK_TX_FREE_ROUTE(exec_ctx, session);
|
||||
FLTSpanGuard(end_transaction);
|
||||
OZ(end_trans(exec_ctx, is_rollback, false, callback));
|
||||
OZ(end_trans(exec_ctx, is_rollback, false, callback, reset_trans_variable));
|
||||
FLT_SET_TAG(trans_id, tx_id);
|
||||
return ret;
|
||||
}
|
||||
@ -246,7 +247,8 @@ int ObSqlTransControl::explicit_end_trans(ObExecContext &exec_ctx, const bool is
|
||||
int ObSqlTransControl::end_trans(ObExecContext &exec_ctx,
|
||||
const bool is_rollback,
|
||||
const bool is_explicit,
|
||||
ObEndTransAsyncCallback *callback)
|
||||
ObEndTransAsyncCallback *callback,
|
||||
bool reset_trans_variable)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool sync = false;
|
||||
@ -278,7 +280,7 @@ int ObSqlTransControl::end_trans(ObExecContext &exec_ctx,
|
||||
}
|
||||
callback->callback(OB_SUCCESS);
|
||||
} else {
|
||||
reset_session_tx_state(session, true);
|
||||
reset_session_tx_state(session, true, reset_trans_variable);
|
||||
exec_ctx.set_need_disconnect(false);
|
||||
}
|
||||
} else {
|
||||
@ -301,7 +303,7 @@ int ObSqlTransControl::end_trans(ObExecContext &exec_ctx,
|
||||
bool reuse_tx = OB_SUCCESS == ret
|
||||
|| OB_TRANS_COMMITED == ret
|
||||
|| OB_TRANS_ROLLBACKED == ret;
|
||||
reset_session_tx_state(session, reuse_tx);
|
||||
reset_session_tx_state(session, reuse_tx, reset_trans_variable);
|
||||
}
|
||||
}
|
||||
if (callback && !is_rollback) {
|
||||
@ -1188,7 +1190,7 @@ int ObSqlTransControl::get_trans_result(ObExecContext &exec_ctx)
|
||||
return get_trans_result(exec_ctx, exec_ctx.get_my_session()->get_trans_result());
|
||||
}
|
||||
|
||||
int ObSqlTransControl::reset_session_tx_state(ObBasicSessionInfo *session, bool reuse_tx_desc)
|
||||
int ObSqlTransControl::reset_session_tx_state(ObBasicSessionInfo *session, bool reuse_tx_desc, bool reset_trans_variable)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
LOG_DEBUG("reset session tx state", KPC(session->get_tx_desc()), K(lbt()));
|
||||
@ -1213,11 +1215,11 @@ int ObSqlTransControl::reset_session_tx_state(ObBasicSessionInfo *session, bool
|
||||
}
|
||||
}
|
||||
session->get_trans_result().reset();
|
||||
session->reset_tx_variable();
|
||||
session->reset_tx_variable(reset_trans_variable);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSqlTransControl::reset_session_tx_state(ObSQLSessionInfo *session, bool reuse_tx_desc)
|
||||
int ObSqlTransControl::reset_session_tx_state(ObSQLSessionInfo *session, bool reuse_tx_desc, bool reset_trans_variable)
|
||||
{
|
||||
int temp_ret = OB_SUCCESS;
|
||||
// cleanup txn level temp tables if this is the txn start node
|
||||
@ -1230,7 +1232,7 @@ int ObSqlTransControl::reset_session_tx_state(ObSQLSessionInfo *session, bool re
|
||||
LOG_WARN_RET(temp_ret, "trx level temporary table clean failed", KR(temp_ret));
|
||||
}
|
||||
}
|
||||
int ret = reset_session_tx_state(static_cast<ObBasicSessionInfo*>(session), reuse_tx_desc);
|
||||
int ret = reset_session_tx_state(static_cast<ObBasicSessionInfo*>(session), reuse_tx_desc, reset_trans_variable);
|
||||
return COVER_SUCC(temp_ret);
|
||||
}
|
||||
|
||||
|
@ -167,19 +167,21 @@ private:
|
||||
class ObSqlTransControl
|
||||
{
|
||||
public:
|
||||
static int reset_session_tx_state(ObSQLSessionInfo *session, bool reuse_tx_desc = false);
|
||||
static int reset_session_tx_state(ObBasicSessionInfo *session, bool reuse_tx_desc = false);
|
||||
static int reset_session_tx_state(ObSQLSessionInfo *session, bool reuse_tx_desc = false, bool active_tx_end = true);
|
||||
static int reset_session_tx_state(ObBasicSessionInfo *session, bool reuse_tx_desc = false, bool active_tx_end = true);
|
||||
static int create_stash_savepoint(ObExecContext &exec_ctx, const ObString &name);
|
||||
static int release_stash_savepoint(ObExecContext &exec_ctx, const ObString &name);
|
||||
static int explicit_start_trans(ObExecContext &exec_ctx, const bool read_only, const ObString hint = ObString());
|
||||
static int explicit_end_trans(ObExecContext &exec_ctx, const bool is_rollback, const ObString hint = ObString());
|
||||
static int implicit_end_trans(ObExecContext &exec_ctx,
|
||||
const bool is_rollback,
|
||||
ObEndTransAsyncCallback *callback = NULL);
|
||||
ObEndTransAsyncCallback *callback = NULL,
|
||||
bool reset_trans_variable = true);
|
||||
static int end_trans(ObExecContext &exec_ctx,
|
||||
const bool is_rollback,
|
||||
const bool is_explicit,
|
||||
ObEndTransAsyncCallback *callback = NULL);
|
||||
ObEndTransAsyncCallback *callback = NULL,
|
||||
bool reset_trans_variable = true);
|
||||
static int rollback_trans(ObSQLSessionInfo *session,
|
||||
bool &need_disconnect);
|
||||
static int do_end_trans_(ObSQLSessionInfo *session,
|
||||
|
@ -68,6 +68,8 @@ int ObStartTransResolver::resolve(const ParseNode &parse_node)
|
||||
start_stmt->set_read_only(true);
|
||||
} else if (IS_READ_WRITE(parse_node.children_[0]->value_)) {
|
||||
start_stmt->set_read_only(false);
|
||||
} else {
|
||||
start_stmt->set_read_only(session_info_->get_tx_read_only());
|
||||
}
|
||||
if (IS_WITH_SNAPSHOT(parse_node.children_[0]->value_)) {
|
||||
start_stmt->set_with_consistent_snapshot(true);
|
||||
|
@ -142,6 +142,7 @@ ObBasicSessionInfo::ObBasicSessionInfo(const uint64_t tenant_id)
|
||||
is_tenant_killed_(0),
|
||||
reused_count_(0),
|
||||
first_need_txn_stmt_type_(stmt::T_NONE),
|
||||
need_recheck_txn_readonly_(false),
|
||||
exec_min_cluster_version_(GET_MIN_CLUSTER_VERSION()),
|
||||
stmt_type_(stmt::T_NONE),
|
||||
labels_(),
|
||||
@ -425,6 +426,7 @@ void ObBasicSessionInfo::reset(bool skip_sys_var)
|
||||
// 不要重置release_to_pool_,原因见属性声明位置的注释。
|
||||
is_tenant_killed_ = 0;
|
||||
first_need_txn_stmt_type_ = stmt::T_NONE;
|
||||
need_recheck_txn_readonly_ = false;
|
||||
exec_min_cluster_version_ = GET_MIN_CLUSTER_VERSION();
|
||||
labels_.reuse();
|
||||
thread_id_ = 0;
|
||||
@ -5357,12 +5359,14 @@ int ObBasicSessionInfo::get_regexp_time_limit(int64_t &v) const
|
||||
return get_sys_variable(SYS_VAR_REGEXP_TIME_LIMIT, v);
|
||||
}
|
||||
|
||||
void ObBasicSessionInfo::reset_tx_variable()
|
||||
void ObBasicSessionInfo::reset_tx_variable(bool reset_next_scope)
|
||||
{
|
||||
LOG_DEBUG("reset tx variable", K(lbt()));
|
||||
reset_first_need_txn_stmt_type();
|
||||
reset_tx_isolation();
|
||||
reset_tx_read_only();
|
||||
if (reset_next_scope) {
|
||||
reset_tx_isolation();
|
||||
reset_tx_read_only();
|
||||
}
|
||||
reset_trans_flags();
|
||||
clear_app_trace_id();
|
||||
}
|
||||
@ -5439,18 +5443,33 @@ void ObBasicSessionInfo::reset_tx_read_only()
|
||||
int ObBasicSessionInfo::check_tx_read_only_privilege(const ObSqlTraits &sql_traits)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (sql_traits.is_cause_implicit_commit_) {
|
||||
reset_tx_read_only();
|
||||
} else {}
|
||||
// pl call stmt and anonymous does not check here,
|
||||
// will be check in ObTransService::start_stmt_sanity_check_
|
||||
if (get_tx_read_only() && !sql_traits.is_readonly_stmt_
|
||||
set_need_recheck_txn_readonly(false);
|
||||
bool read_only = tx_desc_ && tx_desc_->is_in_tx() ? tx_desc_->is_rdonly() : get_tx_read_only();
|
||||
if (!sql_traits.is_readonly_stmt_
|
||||
&& sql_traits.stmt_type_ != ObItemType::T_SP_CALL_STMT
|
||||
&& sql_traits.stmt_type_ != ObItemType::T_SP_ANONYMOUS_BLOCK
|
||||
&& sql_traits.stmt_type_ != ObItemType::T_EXPLAIN) {
|
||||
ret = OB_ERR_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION;
|
||||
|
||||
} else {}
|
||||
if (sql_traits.is_cause_implicit_commit_ && !sql_traits.is_commit_stmt_) {
|
||||
if (sys_vars_cache_.get_tx_read_only()) {
|
||||
// should implicit commit current transaction before report error
|
||||
//
|
||||
// example case:
|
||||
//
|
||||
// set session transaction read only;
|
||||
// set transaction read write;
|
||||
// start transaction;
|
||||
// insert into t values(1);
|
||||
// create table t1(id int); -- error: OB_ERR_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION
|
||||
// rollback;
|
||||
// select * from t where id = 1; -- 1 row found
|
||||
//
|
||||
set_need_recheck_txn_readonly(true);
|
||||
}
|
||||
} else if (read_only) {
|
||||
ret = OB_ERR_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION;
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("CHECK readonly", KP(this), K(sessid_), K(sql_traits.is_readonly_stmt_), K(get_tx_read_only()));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1124,7 +1124,7 @@ public:
|
||||
int set_init_connect(const common::ObString &init_sql);
|
||||
int save_trans_status();
|
||||
// 重置事务相关变量
|
||||
virtual void reset_tx_variable();
|
||||
virtual void reset_tx_variable(bool reset_next_scope = true);
|
||||
transaction::ObTxIsolationLevel get_tx_isolation() const;
|
||||
bool is_isolation_serializable() const;
|
||||
void set_tx_isolation(transaction::ObTxIsolationLevel isolation);
|
||||
@ -1285,6 +1285,8 @@ public:
|
||||
}
|
||||
inline void reset_first_need_txn_stmt_type() { first_need_txn_stmt_type_ = stmt::T_NONE; }
|
||||
inline stmt::StmtType get_first_need_txn_stmt_type() const { return first_need_txn_stmt_type_; }
|
||||
inline void set_need_recheck_txn_readonly(bool need) { need_recheck_txn_readonly_ = need; }
|
||||
inline bool need_recheck_txn_readonly() const { return need_recheck_txn_readonly_; }
|
||||
void set_stmt_type(stmt::StmtType stmt_type) { stmt_type_ = stmt_type; }
|
||||
stmt::StmtType get_stmt_type() const { return stmt_type_; }
|
||||
|
||||
@ -2179,7 +2181,8 @@ private:
|
||||
// type of first stmt which need transaction
|
||||
// either transactional read or transactional write
|
||||
stmt::StmtType first_need_txn_stmt_type_;
|
||||
|
||||
// some Cmd like DDL will commit current transaction, and need recheck tx read only settings before run
|
||||
bool need_recheck_txn_readonly_;
|
||||
//min_cluster_version_: 记录sql执行前当前集群最小的server版本号
|
||||
//解决的问题兼容性问题:
|
||||
// 2.2.3之前的版本会序列化所有的需要序列化的系统变量,
|
||||
|
@ -2916,9 +2916,9 @@ void ObSQLSessionInfo::check_txn_free_route_alive()
|
||||
ObSqlTransControl::check_free_route_tx_alive(*this, txn_free_route_ctx_);
|
||||
}
|
||||
|
||||
void ObSQLSessionInfo::reset_tx_variable()
|
||||
void ObSQLSessionInfo::reset_tx_variable(bool reset_next_scope)
|
||||
{
|
||||
ObBasicSessionInfo::reset_tx_variable();
|
||||
ObBasicSessionInfo::reset_tx_variable(reset_next_scope);
|
||||
set_early_lock_release(false);
|
||||
}
|
||||
void ObSQLSessionInfo::destroy_contexts_map(ObContextsMap &map, common::ObIAllocator &alloc)
|
||||
|
@ -1265,7 +1265,7 @@ public:
|
||||
uint64_t get_conn_res_user_id() const { return conn_res_user_id_; }
|
||||
int on_user_connect(share::schema::ObSessionPrivInfo &priv_info, const ObUserInfo *user_info);
|
||||
int on_user_disconnect();
|
||||
virtual void reset_tx_variable();
|
||||
virtual void reset_tx_variable(bool reset_next_scope = true);
|
||||
ObOptimizerTraceImpl& get_optimizer_tracer() { return optimizer_tracer_; }
|
||||
public:
|
||||
bool has_tx_level_temp_table() const { return tx_desc_ && tx_desc_->with_temporary_table(); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user