Ciao ragazzi, sono alle prime armi con postgresql e con i PDO...
Premesso questo, mi sono 'arenato' facendo qualche prova con delle prepared statement all'interno delle transazioni.

Per le mie prove, ho creato un ambiente così:

5 tabelle: customer, p_orders, p_items, h_orders, h_items.

Le tabelle h_* sono gemelle di p_orders e p_items (fatta eccezione per le sequenze sugli indici), perchè le tabelle h_* sono lo storico delle tabelle p_* (quando queste raggiungono X righe, sposto tutte le righe nelle tabelle 'storico')

Quindi, la mia prima prova è creare una transazione che sposta 50 righe dalle tabelle p_* alle tabelle h_*:

1. Inizio la transazione
2. Copio il dato da p_* a h_*
3. Lo elimino da p_*
4. Se anche solo 1 oggetto o un ordine ha dato errore, faccio il rollback
5. stampo a video 'finito'
6. Commit.

E il codice che ho scritto è (scusate i commenti in inglese ma cerco di abituarmi a scrivere il codice in inglese):
Codice PHP:
<?php
$dbh 
= new PDO('pgsql:host=127.0.0.1;dbname=test''myuser''xxxx');

$rollback false;

$dbh->beginTransaction();

//create the prepared statements
$insert_order $dbh->prepare('INSERT INTO h_orders (id, id_customer, date, code) VALUES (?, ?, ?, ?)');
$insert_items $dbh->prepare('INSERT INTO h_items (id, id_order, descr, price) VALUES (?, ?, ?, ?)');
$delete_order $dbh->prepare('DELETE FROM p_orders WHERE id = ?');

//move the orders from p_orders to h_orders (history)
$qeOrders $dbh->query("SELECT id, id_customer, date, code FROM p_orders LIMIT 1");
while(
$rayOrder $qeOrders->fetch(PDO::FETCH_ASSOC)){
    
//h_orders already contain a row with id 293
    //lets make the query fail
    
$insert_order->execute(array('293'$rayOrder['id_customer'], $rayOrder['date'], $rayOrder['code']));
    
//this is the real execute
    //$insert_order->execute(array($rayOrder['id'], $rayOrder['id_customer'], $rayOrder['date'], $rayOrder['code']));
    //for each order, i move the items too
    
$qeItems $dbh->query("SELECT id, id_order, descr, price FROM p_items WHERE id_order = '" $rayOrder['id'] . "'");
    while(
$rayItem $qeItems->fetch(PDO::FETCH_ASSOC)){
        
$insert_items->execute(array($rayItem['id'], $rayItem['id_order'], $rayItem['descr'], $rayItem['price']));
    }
    
//if everything is ok, delete the order from p_orders
    
$delete_order->execute(array($rayOrder['id']));
}
//in here i'll use a bool var to see if anythings gone wrong and i need to rollback,
//or all good and commit
$dbh->rollBack();
echo 
'finito';
$dbh->commit();
?>
Il problema è che, quando faccio fallire la query inserendo un id duplicato (293), viene lanciato un errore (logico), ma mi termina anche la transazione.
Infatti l'output che mi viene fuori da questa pagina è:
Fatal error: Call to a member function fetch() on a non-object in /srv/www/test-db/test-db-pgsql-08.php on line 23


Sbaglio qualcosa?