Вопрос

Технология деталь

    .
  • go версия 1.2
  • Buillge Postrgres для Go Bmizerany / PQ

Эта проблема сводит меня с ума, и я надеюсь, что кто-то сможет помочь.

Я разработал приложение в Golang, чтобы прочитать данные из базы данных Postgres, и для каждой записи сделайте 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, это, кажется, немного бросает отступ) Осница, которую вы можете видеть, я начинаю BNUT, не закрываю транзакцию. Это вызывает проблему в стороне PG вещей, где каждый выбор оставлен в состоянии «холостого хода транзакции».

Я пробовал tx.commit () и tx.rollback () и в обоих случаях я получаю ошибки:

"unknown response for simple query '3'"
.

или

"unknown response for simple query 'D'"
.

Хо мне успешно закрыть транзакцию в Go? Я надеюсь получить нашу pgbouncer.ini обновил, чтобы позволить мне перейти на lib / pq для библиотеки драйверов, но я не уверен, что это будет напрямую помочь этой проблеме.

Так, как я правильно закрыл объект TX или есть ли способ заставить идти не использовать подготовленные заявления под капотом?

спасибо Натан

Я пытался немного изменить вещи:

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'
.

Однако я должен указать, что это при попытке выбора оператора во второй раз. Это приложение выбирает пакет, имеет дело с ним, а затем выбирает последующую партию. Эта ошибка происходит на втором выборе. Нет проблем с очень первым выбором.

Это было полезно?

Решение

Для кого-то еще, кто попадает в это, я решил это.

Код, который у меня было возвращать объект строк к вызывающему коду (не показано) выше.Закрытие транзакции до того, как строки были прочитаны, казалось, причиной проблемы.Я не полностью понимаю, почему, пожалуйста, уточните, если вы сделаете.

Теперь я возвращаю как строки, так и объект транзакции.Затем, когда я прочитал все строки, которые я откатываю транзакцию.Это держит все, что работает.

спасибо Натан

Другие советы

TX.Query Возвращает экземпляр SQL.Rows, который является курсором к набору результатов.Данные не обязательно были получены, пока вы итерация этого курсора.Транзакция должна оставаться открытой, когда вы итерация курсора.

Вот почему вы больше не могли повторять курсор, как только транзакция была закрыта.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top