문제

기술 세부 사항

  • GO 버전 1.2
  • 포스 트레 그레스 GO BMIZERANY / PQ

이 문제는 나를 화나게하고 있습니다. 누군가가 도움이 될 수 있기를 바랍니다.

Postgres 데이터베이스에서 데이터를 읽으려면 Golang에서 응용 프로그램을 개발했으며 각 레코드가 HTTP 요청을 수행 한 다음 데이터베이스를 업데이트합니다.

이것은 모두 충분히 간단합니다. 그러나 우리는 PGBOuncer를 제자리에 가지고 있습니다. pgbouncer에 대한 구성은 준비된 진술을 지원하지 않습니다. 준비된 문장에서 모든 쿼리를 자동으로 감싼다. pgbouncer에 대한 이런 방식은 거래를 설정하는 것입니다. 그것은 모두 삽입 / 업데이트 / 삭제와 같은 것들에 대해 모두 잘하고 있습니다.

SELECT 문의 경우 트랜잭션에서 포장하고 있습니다 :

func TransactionQuery(db *sql.DB, baseQuery string) (rows *sql.Rows, code int, err error) {
        tx, txErr := db.Begin()
        if txErr != nil {
            return nil, -1, txErr
        }

        selectStmt, prepErr := tx.Prepare(baseQuery)
        if prepErr != nil {
            return nil, -1, fmt.Errorf("Failed to prepare statment: %s Error: %v", baseQuery, prepErr)
        }

        defer func() {
            if stmtErr := selectStmt.Close(); stmtErr != nil {
                rows = nil
                code = -2
                err = fmt.Errorf("Failed to close statement: %v.", stmtErr)
            }
        }()

        rows, err = selectStmt.Query()
        if err != nil {
            fmt.Errorf("Failed to retrieve data: %v", err)
            return nil, -1, err
        }
        return rows, 0, nil
    }
.

(HHMM, 그만두고 조금 벗어난 것처럼 보입니다) 엉덩이는 내가 거래를 닫지 않는 밤을 시작하는 것을 볼 수 있습니다. 이로 인해 모든 선택이 트랜잭션의 '유휴 상태'상태에 남아있는 것들의 PG 측면에서 문제가 발생합니다.

ix.commit () 및 tx.rollback ()을 시도했고 두 경우 모두 오류가 발생합니다.

"unknown response for simple query '3'"
.

또는

"unknown response for simple query 'D'"
.

Ho Go에서 거래를 성공적으로 닫습니까? 저는 PgBouncer.ini가 드라이버 라이브러리에 대한 lib / pq로 전환 할 수 있도록 업데이트되었지만이 문제를 직접적으로 도울 수 있는지 확실하지 않습니다.

그래서, 어떻게 TX 객체를 올바르게 닫거나 강제로 준비된 진술을 사용하지 않도록 강제로가는 방법이 있습니까?

고맙습니다 Nathan

조금만 변경하려고 시도했습니다.

func TransactionQuery(db *sql.DB, baseQuery string) (rows *sql.Rows, code int, err error) {
    tx, txErr := db.Begin()
    if txErr != nil {
        return nil, -1, txErr
    }

    /*selectStmt, prepErr := tx.Prepare(baseQuery)
      if prepErr != nil {
          return nil, -1, fmt.Errorf("Failed to prepare statment: %s Error: %v", baseQuery, prepErr)
      }
    */
    rows, err = tx.Query(baseQuery)
    if err != nil {
        fmt.Errorf("Failed to retrieve data: %v", err)
        return nil, -1, err
    }

    /*    if stmtErr := selectStmt.Close(); stmtErr != nil {
          rows = nil
          code = -2
          err = fmt.Errorf("Failed to close statement: %v.", stmtErr)
      }*/

    if txCloseErr := tx.Commit(); txErr != nil {
        rows = rows
        code = -3
        err = txCloseErr
    }
    return rows, 0, nil
}
.

이 코드로 로그에서 볼 수있는 것 :

pq: unexpected describe rows response: '3'
.

그러나 두 번째 시간 동안 SELECT 문을 시도 할 때이를 지적해야합니다. 이 응용 프로그램은 일괄 처리를 선택하고이를 처리 한 다음 후속 배치를 선택합니다. 이 오류는 두 번째 선택에서 발생합니다. 첫 번째 선택에는 문제가 없습니다.

도움이 되었습니까?

해결책

이 문제를 해결하는 다른 사람을 위해이 문제를 해결했습니다.

내가 rows 오브젝트를 위의 호출 코드 (미도시)로 되돌려 놓은 코드.행을 읽기 전에 트랜잭션을 닫으면 문제의 원인이되는 것처럼 보였습니다.나는 당신이 그렇게하는지 명확하게하는 이유를 완전히 이해하지 못합니다.

이제 행과 트랜잭션 객체를 모두 반환합니다.그런 다음 트랜잭션을 롤백하는 모든 행을 읽을 때.이것은 모든 일을 계속해서 작동합니다.

고맙습니다 Nathan

다른 팁

tx.query 결과 집합의 커서 인 sql.rows의 인스턴스를 반환합니다.이 커서를 반복하는 동안 데이터가 반드시 검색되지는 않습니다.트랜잭션은 커서를 반복하는 동안 열려 있어야합니다.

트랜잭션이 닫히면 더 이상 커서를 반복 할 수 없었습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top