ERROR: canceling statement due to user request

8461 단어 작업 일지
환경: jdk1.8 구조: Spring Boot 1.5.7 + Mybatis 3.4.3 + Druid + PostgreSQL JDBC Driver나는 PostgreSQL을 사용하여 몇 가지 조회 타임즈에서 오류를 실행했다. 반나절의 시간을 써서 이 오류가 발생한 원인을 이해한 후에 여기서 총결하기로 결정했다.

ERROR: 사용자 요청으로 인해 예외 투척 원인이 발생하여 취소합니다.


이 오류를 보고한 주요 원인은 글자의 의미와 일치하기 때문이다. "사용자의 요청으로 현재 조회의 상태를 취소했습니다."
Caused by: org.postgresql.util.PSQLException: ERROR: canceling statement due to user request
	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2477)
	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2190)
	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:300)
	at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:428)
	at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:354)
	at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:169)
	at org.postgresql.jdbc.PgPreparedStatement.execute(PgPreparedStatement.java:158)

좀 경솔하게 설명했을 수도 있지만, 여기서도 더 상세하게 설명할 방법이 없다.대체적으로 당신의 코드에 현재 검색을 취소하는 코드가 설정되어 있기 때문에 이 이상을 던진다는 것입니다.예외적인 원인은 이 함수java.sql.Statement를 실행했기 때문일 수 있습니다.
// java.sql.Statement:248-259
    /**
     * Cancels this Statement object if both the DBMS and
     * driver support aborting an SQL statement.
     * This method can be used by one thread to cancel a statement that
     * is being executed by another thread.
     *
     * @exception SQLException if a database access error occurs or
     * this method is called on a closed Statement
     * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
     * this method
     */
    void cancel() throws SQLException;
PostgreSQL JDBC Driver 드라이브에서 이 방법에 대한 구현 코드는 다음과 같습니다.
//org.postgresql.jdbc.PgStatement:595-606
  public void close() throws SQLException {
    // closing an already closed Statement is a no-op.
    if (isClosed) {
      return;
    }
    cleanupTimer();
    closeForNextExecution();
    isClosed = true;
  }

내가 현재 직면하고 있는 두 가지 문제는 아마도 이 잘못을 폭로할 것이다.
  • 사용자가 Http 요청을 발기하면 이 요청이 Sql 조회를 촉발한 후 데이터가 돌아오지 않을 때 사용자가 이 요청을 취소하면 이 이상을 던진다.
  • Mybatis의 프로필mybatis-config.xmldefaultStatementTimeout 속성(단위:초)을 설정한 후 sql의 조회 시간이 이 설정 시간을 초과하면 이 이상을 던집니다.

  • 첫 번째 상황은 그다지 확실하지 않다.그러나 두 번째 상황에서 구동 코드PostgreSQL JDBC Driver는 조회 전에 defaultStatementTimeout 설정된 시간에 따라 타이머를 생성합니다.
    //org.postgresql.jdbc:872-888
      private void startTimer() {
        /*
         * there shouldn't be any previous timer active, but better safe than sorry.
         */
        cleanupTimer();
        STATE_UPDATER.set(this, StatementCancelState.IN_QUERY);
        if (timeout == 0) {
          return;
        }
        TimerTask cancelTask = new TimerTask() {
          public void run() {
            try {
              if (!CANCEL_TIMER_UPDATER.compareAndSet(PgStatement.this, this, null)) {
                // Nothing to do here, statement has already finished and cleared
                // cancelTimerTask reference
                return;
              }
              PgStatement.this.cancel(); //** **
            } catch (SQLException e) {
            }
          }
        };
        CANCEL_TIMER_UPDATER.set(this, cancelTask);
        connection.addTimerTask(cancelTask, timeout);// , 
      }
    

    검색 시간이 타이머 설정 시간을 초과하면 타이머가 시작되고 이번 ql 실행을 닫습니다.실행이 끝난 후 조회의 순환 판단이 취소되어 이상이 발생했을 때 이 이상을 포장하여 던집니다.

    좋은 웹페이지 즐겨찾기