From a practical view there are two types of error messages when using transactions:
-"Normal" errors: in this case, the application should stop the current process and show an error message to the user.
-Deadlock errors. This shows that the deadlock detection process of PostgreSQL found a circle of dependency, and broke it by rolling back the transaction in one of the processes, which gets this error msg. In this case, the application should not stop, but repeat the transaction.
I found no discrete way to find out which case are we dealing with. This interface doesn't support error codes, so we have to search for patterns in the message text.
Here is an example for PostgreSQL database connection class. It throws a PostgresException on "normal" errors, and DependencyException in the case of a broken deadlock, when we have to repeat the transaction.
postgres.php:
<?php
class PostgresException extends Exception {
function __construct($msg) { parent::__construct($msg); }
}
class DependencyException extends PostgresException {
function __construct() { parent::__construct("deadlock"); }
}
class pg {
public static $connection;
private static function connect() {
self::$connection = @pg_connect("dbname=foodb user=foouser password=foopasswd");
if (self::$connection === FALSE) {
throw(new PostgresException("Can't connect to database server."));
}
}
public static function query($sql) {
if (!isset(self::$connection)) {
self::connect();
}
$result = @pg_query(self::$connection, $sql);
if ($result === FALSE) {
$error = pg_last_error(self::$connection);
if (stripos($error, "deadlock detected") !== false) throw(new DependencyException());
throw(new PostgresException($error.": ".$sql));
}
$out = array();
while ( ($d = pg_fetch_assoc($result)) !== FALSE) {
$out[] = $d;
}
return $out;
}
}
?>
It should be used in this way:
test.php:
<?php
include("postgres.php");
do {
$repeat = false;
try {
pg::query("begin");
...
$result = pg::query("SELECT * FROM public.kitten");
...
pg::query("commit");
}
catch (DependencyException $e) {
pg::query("rollback");
$repeat = true;
}
} while ($repeat);
?>
The normal errors should be caught at the frontend.
Tamas
pg_last_error
(PHP 4 >= 4.2.0, PHP 5)
pg_last_error — Lit le dernier message d'erreur sur la connexion
Description
$connection
] )
pg_last_error() retourne le dernier message d'erreur
pour une connexion connection.
Les messages d'erreur peuvent être écrasés par des appels internes à l'extension PostgreSQL (libpq) : il se peut que le message retourné ne soit pas approprié, notamment si plusieurs erreurs ont eu lieu dans le module.
Utilisez pg_result_error(), pg_result_error_field(), pg_result_status() et pg_connection_status() pour améliorer la gestion des erreurs.
Note:
Auparavant, cette fonction s'appelait pg_errormessage().
Liste de paramètres
-
connection -
La ressource de connexion de la base de données PostgreSQL. Lorsque
connectionn'est pas présent, la connexion par défaut est utilisée. La connexion par défaut est la dernière connexion faite par pg_connect() ou pg_pconnect().
Valeurs de retour
Une chaîne de caractères contenant le dernier message d'erreur sur la connexion
connection ou FALSE en cas d'erreur.
Exemples
Exemple #1 Exemple avec pg_last_error()
<?php
$dbconn = pg_connect("dbname=publisher") or die("Connexion impossible");
// Requête qui échoue
$res = pg_query($dbconn, "select * from doesnotexist");
echo pg_last_error($dbconn);
?>
Voir aussi
- pg_result_error() - Lit le message d'erreur associé à un résultat
- pg_result_error_field() - Retourne un champ individuel d'un rapport d'erreur
