[CP] [to #45595870]close session cursor when pl exec fail

This commit is contained in:
LiuYoung00 2023-09-20 15:59:42 +00:00 committed by ob-robot
parent 497521f38b
commit e55cfdf335
3 changed files with 39 additions and 40 deletions

View File

@ -2677,6 +2677,7 @@ int ObPLExecState::final(int ret)
int64_t cursor_id = NULL == cursor ? -1 : cursor->get_id(); int64_t cursor_id = NULL == cursor ? -1 : cursor->get_id();
if (OB_SUCCESS == tmp_ret && NULL != cursor && cursor->is_session_cursor() if (OB_SUCCESS == tmp_ret && NULL != cursor && cursor->is_session_cursor()
&& NULL != ctx_.exec_ctx_->get_my_session()) { && NULL != ctx_.exec_ctx_->get_my_session()) {
// when execute fail. should use session close cursor
ObSQLSessionInfo *session = ctx_.exec_ctx_->get_my_session(); ObSQLSessionInfo *session = ctx_.exec_ctx_->get_my_session();
tmp_ret = session->close_cursor(cursor_id); tmp_ret = session->close_cursor(cursor_id);
} }
@ -2711,15 +2712,23 @@ int ObPLExecState::final(int ret)
LOG_WARN("failed to destruct pl object", K(i), K(tmp_ret)); LOG_WARN("failed to destruct pl object", K(i), K(tmp_ret));
} }
} else if (func_.get_variables().at(i).is_cursor_type()) { } else if (func_.get_variables().at(i).is_cursor_type()) {
// 函数结束这儿还需要close cursor,因为如果有异常,block结束除的close cursor就走不到,这儿还需要关闭 int tmp_ret = OB_SUCCESS;
if (OB_FAIL(ret)) { ObPLCursorInfo *cursor = NULL;
ObPLCursorInfo *cursor = NULL; ObObjParam param;
ObObjParam param; ObSPIService::ObCusorDeclareLoc loc;
ObSPIService::ObCusorDeclareLoc loc; ObSQLSessionInfo *session = ctx_.exec_ctx_->get_my_session();
tmp_ret = ObSPIService::spi_get_cursor_info(&ctx_, func_.get_package_id(), tmp_ret = ObSPIService::spi_get_cursor_info(&ctx_, func_.get_package_id(),
func_.get_routine_id(), func_.get_routine_id(),
i, cursor, param, loc); i, cursor, param, loc);
if (OB_SUCCESS == tmp_ret) { if (OB_SUCCESS == tmp_ret && NULL != cursor) {
if (0 == cursor->get_ref_count() && (cursor->is_session_cursor() || cursor->is_ref_by_refcursor())) {
// when refcount is 0. should use session close cursor
ObSQLSessionInfo *session = ctx_.exec_ctx_->get_my_session();
tmp_ret = session->close_cursor(cursor->get_id());
ret = OB_SUCCESS == ret ? tmp_ret : ret;
LOG_INFO("close session cursor after pl exec.", K(ret), K(tmp_ret), K(cursor->get_id()));
} else if (OB_FAIL(ret)) {
// 函数结束这儿还需要close cursor,因为如果有异常,block结束除的close cursor就走不到,这儿还需要关闭
// 这儿为啥可能为null // 这儿为啥可能为null
/* /*
* *
@ -2743,38 +2752,20 @@ int ObPLExecState::final(int ret)
* c1 cursor initc2没有调用execption打断final函数里面调用cursor close * c1 cursor initc2没有调用execption打断final函数里面调用cursor close
* obj就是nullc2没有调用cursor init goto也可能导致执行流变动open就去close * obj就是nullc2没有调用cursor init goto也可能导致执行流变动open就去close
*/ */
if (OB_NOT_NULL(cursor)) { if (OB_SUCCESS != ObSPIService::spi_cursor_close(&ctx_, func_.get_package_id(),
tmp_ret = ObSPIService::spi_cursor_close( func_.get_routine_id(), i, true)) {
&ctx_, func_.get_package_id(), func_.get_routine_id(), i, true); LOG_WARN("failed to get cursor info", K(tmp_ret),
K(func_.get_package_id()), K(func_.get_routine_id()), K(i));
} }
} else { } else {
LOG_WARN("failed to get cursor info", K(tmp_ret), // local cursor must be closed.
K(func_.get_package_id()), K(func_.get_routine_id()), K(i)); if (!cursor->is_session_cursor() && !cursor->is_ref_by_refcursor()) {
} if (OB_SUCCESS != ObSPIService::spi_cursor_close(&ctx_, func_.get_package_id(),
if (OB_SUCCESS != tmp_ret) { func_.get_routine_id(), i, true)) {
LOG_WARN("failed to close cursor", K(tmp_ret), LOG_WARN("failed to close cursor info", K(tmp_ret),
K(func_.get_package_id()), K(func_.get_routine_id()), K(i)); K(func_.get_package_id()), K(func_.get_routine_id()), K(i));
} }
} else {
// local cursor must be closed.
ObPLCursorInfo *cursor = NULL;
ObObjParam param;
ObSPIService::ObCusorDeclareLoc loc;
tmp_ret = ObSPIService::spi_get_cursor_info(&ctx_, func_.get_package_id(),
func_.get_routine_id(),
i, cursor, param, loc);
if (OB_SUCCESS == tmp_ret) {
if (OB_NOT_NULL(cursor) && (!cursor->is_session_cursor()
&& !cursor->is_ref_by_refcursor())) {
tmp_ret = ObSPIService::spi_cursor_close(&ctx_, func_.get_package_id(),
func_.get_routine_id(), i, true);
} else {
LOG_WARN("failed to close cursor info", K(tmp_ret),
K(func_.get_package_id()), K(func_.get_routine_id()), K(i));
} }
} else {
LOG_WARN("failed to get cursor info", K(tmp_ret),
K(func_.get_package_id()), K(func_.get_routine_id()), K(i));
} }
} }
} }

View File

@ -834,7 +834,11 @@ public:
in_forall_ = false; in_forall_ = false;
save_exception_ = false; save_exception_ = false;
forall_rollback_ = false; forall_rollback_ = false;
cursor_flag_ = CURSOR_FLAG_UNDEF; if (is_session_cursor()) {
cursor_flag_ = SESSION_CURSOR;
} else {
cursor_flag_ = CURSOR_FLAG_UNDEF;
}
// ref_count_ = 0; // 这个不要清零,因为oracle在close之后,它的ref count还是保留的 // ref_count_ = 0; // 这个不要清零,因为oracle在close之后,它的ref count还是保留的
is_scrollable_ = false; is_scrollable_ = false;
last_execute_time_ = 0; last_execute_time_ = 0;

View File

@ -5746,7 +5746,11 @@ int ObSPIService::spi_add_ref_cursor_refcount(ObPLExecCtx *ctx, ObObj *cursor, i
OZ (cursor_close_impl(ctx, cursor_info, true, OB_INVALID_ID, OB_INVALID_ID, true)); OZ (cursor_close_impl(ctx, cursor_info, true, OB_INVALID_ID, OB_INVALID_ID, true));
} }
} else { } else {
LOG_DEBUG("spi process return ref cursor, cursor not open"); // cursor maybe closed already
if (-1 == addend) {
OX (cursor_info->dec_ref_count());
}
LOG_DEBUG("spi process return ref cursor, cursor not open", K(cursor_info->get_ref_count()));
} }
} }
} else { } else {