Ben bir LAPP ortamda (linux apache postgresql php) üzerinde çalışmak, ve ben sadece (mümkün ise) işlem içinde hazırlanmış deyimi nasıl kullanılacağını öğrenmek için triyn ediyorum.
Ben kod kelimeleri daha sonra daha iyi açıklamak umuyoruz:
Örnek 1, basit işlem:
BEGIN;
INSERT INTO requests (user_id, description, date) VALUES ('4', 'This dont worth anything', NOW());
UPDATE users SET num_requests = (num_requests + 1) WHERE id = '4';
--something gone wrong, cancel the transaction
ROLLBACK;
UPDATE users SET last_activity = NOW() WHERE id = '4'
COMMIT;
I doğru işlem undestood, yukarıdaki örnekte, veritabanındaki tek etkisi siz ... last_activity güncelleme olacak?
I php o işlem (her iki PDO veya pg_ yöntemleri ile) kullanmaya çalışırsanız kodu, (örneğin 2) gibi görünmelidir:
/* skip the connection */
pg_query($pgConnection, "BEGIN");
pg_query($pgConnection, "INSERT INTO requests (user_id, description, date) VALUES ('$id_user', 'This dont worth anything', NOW())");
pg_query($pgConnection, "UPDATE users SET num_requests = (num_requests + 1) WHERE id = '$id_user'");
//something gone wrong, cancel the transaction
pg_query($pgConnection, "ROLLBACK");
pg_query($pgConnection, "UPDATE users SET last_activity = NOW() WHERE id = '$id_user'");
pg_query($pgConnection, "COMMIT");
Ve bu gayet iyi çalışıyor. Belki çirkin (önerim her zaman açığız) görmek için, ama seem çalışmak
I hazırlanan tablolarda (i örnek 2'de hazırlanan tabloların kullanımı çok yararlı olmadığını biliyoruz) ile örnek 2 öznelerden biri çalıştığınızda Neyse, benim sorunum gel
Örnek 3:
/* skip the connection */
pg_prepare($pgConnection, 'insert_try', "INSERT INTO requests (user_id, description, date) VALUES ('$1', '$2', $3)");
pg_query($pgConnection, "BEGIN");
pg_execute($pgConnection, 'insert_try', array($user_id, 'This dont worth anything', date("Y-m-d")));
/* and so on ...*/
Peki, örneğin 3 sadece dont iş, hazır deyim etkili olacak eğer işlem geri alma nedeniyle.
Yani, hazırlanan tablolar işlemde kullanılamaz, ya da ben yanlış yol alıyorum?
EDIT:
Bazı PDO ile çalıştıktan sonra, ben bu noktada geldi ediyorum:
<?php
$dbh = new PDO('pgsql:host=127.0.0.1;dbname=test', 'myuser', 'xxxxxx');
$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'])) OR var_dump($dbh->errorInfo());
//this is the real execute
//$insert_order->execute(array($rayOrder['id'], $rayOrder['id_customer'], $rayOrder['date'], $rayOrder['code'])) OR die(damnIt('insert_order'));
//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'] . "'") OR var_dump($dbh->errorInfo());
while($rayItem = $qeItems->fetch(PDO::FETCH_ASSOC)){
$insert_items->execute(array($rayItem['id'], $rayItem['id_order'], $rayItem['descr'], $rayItem['price'])) OR var_dump($dbh->errorInfo());
}
//if everything is ok, delete the order from p_orders
$delete_order->execute(array($rayOrder['id'])) OR var_dump($dbh->errorInfo());
}
//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();
//$dbh->commit();
?>
Yukarıdaki kod, bu çıkışı ile başarısız:
array (3) {[0] => string (5) "00000" [1] => int (7) [2] => string (62) "HATA: anahtar benzersiz kısıtlaması ihlal yinelenen" id_h_orders ""}
array (3) {[0] => string (5) "25P02" [1] => int (7) [2] => string (87) "HATA: Geçerli işlem komutları işlem bloğunun sonuna kadar ihmal, iptal edilir "}
Ölümcül hata: satır 23 / srv/www/test-db/test-db-pgsql-08.php olmayan bir nesne üzerinde () getirme üye işlev çağrısı
Yani, gibi görünüyor zaman ilk ... işlem otomatik olarak iptal edilir (id 293 ile bir) başarısız yürütmek yapar PDO oto-geri alma, ya da başka bir şey?
Amacım ilk büyük while döngüsü tamamlamak, ve sonunda, bayrak gibi bir bool var kullanarak, işlem geri veya işlemeye karar etmektir.