Pg transaction status: примеры (PHP)
pg_transaction_status(PgSql\Connection $connection): intФункция pg_transaction_status в PHP возвращает текущий статус транзакции для указанного соединения с базой данных PostgreSQL. Она используется для определения состояния сервера в асинхронных операциях или после попытки установления соединения. Это позволяет скрипту реагировать на различные сценарии, например, на сбои в сети или долгое выполнение запросов.
Функция принимает один обязательный аргумент:
- $connection (ресурс подключения PostgreSQL) - Соединение к базе данных PostgreSQL, полученное через
pg_connect()илиpg_pconnect().
Функция возвращает целочисленное значение (int), соответствующее одной из предопределенных констант.
<?php
$conn = pg_connect("host=localhost dbname=test user=postgres");
$status = pg_transaction_status($conn);
echo 'Статус: ';
switch ($status) {
case PGSQL_TRANSACTION_IDLE:
echo 'Сервер ожидает команду';
break;
case PGSQL_TRANSACTION_ACTIVE:
echo 'Сервер выполняет транзакцию';
break;
case PGSQL_TRANSACTION_INTRANS:
echo 'Сервер находится в состоянии транзакции';
break;
case PGSQL_TRANSACTION_INERROR:
echo 'Сервер находится в состоянии транзакции с ошибкой';
break;
case PGSQL_TRANSACTION_UNKNOWN:
echo 'Соединение неактивно или сбой';
break;
}
?>Статус: Сервер ожидает команду
<?php
$conn = pg_connect("host=localhost dbname=test user=postgres");
echo 'До BEGIN: ' . pg_transaction_status($conn) . '\n';
pg_query($conn, 'BEGIN');
echo 'После BEGIN: ' . pg_transaction_status($conn) . '\n';
pg_query($conn, 'SELECT 1');
echo 'После SELECT: ' . pg_transaction_status($conn) . '\n';
pg_query($conn, 'COMMIT');
echo 'После COMMIT: ' . pg_transaction_status($conn) . '\n';
?>До BEGIN: 0 После BEGIN: 1 После SELECT: 1 После COMMIT: 0
Прямых аналогов для получения статуса транзакции в PGSQL не существует. Однако некоторые функции предоставляют косвенную информацию:
- pg_connection_status($connection) - Возвращает статус самого соединения (PGSQL_CONNECTION_OK, PGSQL_CONNECTION_BAD). Показывает, активно ли соединение, но не состояние транзакции на сервере.
- pg_result_status($result) - Возвращает статус результата запроса (PGSQL_EMPTY_QUERY, PGSQL_COMMAND_OK и т.д.). Полезен для анализа результата последней выполненной команды, но не глобального статуса транзакции.
Функцию pg_transaction_status предпочтительно использовать, когда требуется точное понимание состояния серверной транзакции, особенно в асинхронных или сложных сценариях управления соединением.
В psycopg2 явной функции для статуса транзакции нет, но состояние можно проверить через атрибуты соединения и использование connection.get_transaction_status().
import psycopg2
conn = psycopg2.connect("dbname=test user=postgres")
print(conn.get_transaction_status()) # 0 = IDLE
cur = conn.cursor()
cur.execute("BEGIN")
print(conn.get_transaction_status()) # 2 = INTRANS
conn.commit()
print(conn.get_transaction_status()) # 0 = IDLE0 2 0
В библиотеке pg статус транзакции не предоставляется явно. Управление осуществляется через запросы BEGIN/COMMIT и обработку ошибок в асинхронных функциях.
const { Client } = require('pg');
const client = new Client();
await client.connect();
// Явного статуса нет. Состояние определяется контекстом выполнения запросов.
await client.query('BEGIN');
// Транзакция активна
await client.query('COMMIT');
// Транзакция завершенаPg transaction status в MySQL
В MySQL аналогом является команда SHOW SESSION STATUS LIKE 'tx_isolation' или проверка переменной @@session.transaction_read_only, но они показывают уровень изоляции, а не текущее состояние. Более близко состояние можно получить через SELECT @@in_transaction (в некоторых драйверах, например, для MySQLi).
<?php
$status = pg_transaction_status("not_a_connection");
var_dump($status);
?>Warning: pg_transaction_status() expects parameter 1 to be resource, string given
<?php
$conn = pg_connect("host=localhost dbname=test user=postgres");
pg_close($conn);
$status = pg_transaction_status($conn);
echo $status;
?>2 // PGSQL_TRANSACTION_UNKNOWN, так как соединение недействительно
Ошибкой является прямое сравнение с числами без использования предопределенных констант, что снижает читаемость кода.
// Плохо
if (pg_transaction_status($conn) == 1) { /* код */ }
// Хорошо
if (pg_transaction_status($conn) === PGSQL_TRANSACTION_ACTIVE) { /* код */ }Функция pg_transaction_status была добавлена в PHP начиная с версии 5.2.0. Значительных изменений в её поведении или сигнатуре в последних основных версиях PHP (включая PHP 8.x) не было. Она остается стабильным и неизменным API для работы с PostgreSQL.
<?php
$conn = pg_connect("host=localhost dbname=test user=postgres");
function logTransactionStatus($connection, $step) {
$statusMap = [
PGSQL_TRANSACTION_IDLE => 'IDLE',
PGSQL_TRANSACTION_ACTIVE => 'ACTIVE',
PGSQL_TRANSACTION_INTRANS => 'INTRANS',
PGSQL_TRANSACTION_INERROR => 'INERROR',
PGSQL_TRANSACTION_UNKNOWN => 'UNKNOWN'
];
$code = pg_transaction_status($connection);
echo "Шаг {$step}: {$statusMap[$code]} ({$code})\n";
}
logTransactionStatus($conn, 'Инициализация'); // IDLE
pg_query($conn, 'BEGIN WORK');
logTransactionStatus($conn, 'После BEGIN'); // INTRANS
// Имитация долгой операции
pg_query($conn, 'SELECT pg_sleep(0.1)');
logTransactionStatus($conn, 'После SELECT'); // INTRANS (может быть ACTIVE во время выполнения)
pg_query($conn, 'SAVEPOINT my_savepoint');
logTransactionStatus($conn, 'После SAVEPOINT'); // INTRANS
pg_query($conn, 'ROLLBACK TO SAVEPOINT my_savepoint');
logTransactionStatus($conn, 'После ROLLBACK TO SAVEPOINT'); // INTRANS
pg_query($conn, 'COMMIT');
logTransactionStatus($conn, 'После COMMIT'); // IDLE
?><?php
// Предположим, соединение установлено
$conn = pg_connect("host=localhost dbname=test user=postgres");
// Имитация сбоя (например, остановка сервера БД)
// В реальности это может произойти асинхронно
// Попытка выполнить запрос на разорванном соединении
@pg_query($conn, 'SELECT 1');
// Проверка статуса транзакции после возможного сбоя
$txStatus = pg_transaction_status($conn);
$connStatus = pg_connection_status($conn);
if ($connStatus === PGSQL_CONNECTION_BAD || $txStatus === PGSQL_TRANSACTION_UNKNOWN) {
echo "Соединение разорвано. Необходимо переподключение.\n";
// Логика переподключения...
}
?>