diff --git a/src/sql/ob_result_set.cpp b/src/sql/ob_result_set.cpp index 465ee4106..480f44d95 100644 --- a/src/sql/ob_result_set.cpp +++ b/src/sql/ob_result_set.cpp @@ -974,7 +974,26 @@ 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 && plan.is_need_trans()) { + if (!explicit_trans && ac) { + // Query like `select 1` will keep next scope set transaction xxx valid + // for example: + // set session transaction read only; + // set @@session.autocommit=1; + // set transaction read write; + // select 1; + // insert into t values(1); -- this will be success + // + // so, can not reset these transaction variables + // + // must always commit/rollback the transactional state in `ObTxDesc` + // for example: + // set session transaction isolation level SERIALIZABLE + // -- UDF with: select count(1) from t1; + // select UDF1() from dual; -- PL will remain transctional state after run UDF1 + // + // after execute UDF1, snapshot is kept in ObTxDesc, must cleanup before run + // other Query + bool reset_tx_variable = plan.is_need_trans(); ObPhysicalPlanCtx *plan_ctx = NULL; if (OB_ISNULL(plan_ctx = get_exec_context().get_physical_plan_ctx())) { ret = OB_ERR_UNEXPECTED; @@ -988,7 +1007,9 @@ OB_INLINE int ObResultSet::auto_end_plan_trans(ObPhysicalPlan& plan, // 因为InnerSQL没有走Obmp_query接口,而是直接操作ResultSet int save_ret = ret; if (OB_FAIL(ObSqlTransControl::implicit_end_trans(get_exec_context(), - is_rollback))) { + is_rollback, + NULL, + reset_tx_variable))) { if (OB_REPLICA_NOT_READABLE != ret) { LOG_WARN("sync end trans callback return an error!", K(ret), K(is_rollback), KPC(my_session_.get_tx_desc())); @@ -1019,7 +1040,8 @@ OB_INLINE int ObResultSet::auto_end_plan_trans(ObPhysicalPlan& plan, my_session_.get_end_trans_cb().set_last_error(ret); ret = ObSqlTransControl::implicit_end_trans(get_exec_context(), is_rollback, - &my_session_.get_end_trans_cb()); + &my_session_.get_end_trans_cb(), + reset_tx_variable); // NOTE: async callback client will not issued if: // 1) it is a rollback, which will succeed immediately // 2) the commit submit/starting failed, in this case