Hareketler ve Ototeslim
Bir veritabanına PDO üzerinden bağlantı kuracaksanız, sorgulara başlamadan
PDO'nun toplu hareketleri nasıl yönettiğini bilmek zorundasınız. Daha önce
toplu hareketler (transactions) ile çalışmadıysanız
şu dört ana özelliği bilmenizde yarar var: Dayanıklılık, Atomsallık, Yalıtım
ve Tutarlılık (DAYT). Layman kuralları gereğince, bir toplu hareket olarak
yürütülen bir işleme başlanıldığı takdirde, aşamalar halinde bile yürütülse,
diğer bağlantılarla etkileşime girmeksizin veritabanına güvenle uygulanacağı
garanti edilir. Ayrıca, toplu hareketler, istediğiniz taktirde (sanki işleme
hiç başlamamışsınız gibi) otomatik olarak geri alınır ve betiğinizin
hatalarla daha kolay başa çıkmasını sağlar.
Toplu hareketler genellikle bir defada uygulanacak işlemlerin bir betik (bir
SQL deyimleri betiği) haline getirilmesiyle oluşur. Bunun
bu güncellemelerin verimliliğini esaslı bir şekilde arttırmak gibi bir yan
etkisi de vardır. Başka bir deyişle, toplu hareketler betiğinizin daha hızlı
ve daha tutarlı çalışmasını sağlar (ancak, bunu sağlamak için toplu
hareketleri doğru yerde kullanmanız gerekir).
Talihsizliğe bakın ki, her veritabanı toplu hareketleri desteklemez, bu
yüzden PDO, önce bağlantı açılmasını gerektiren ve ototeslim kipi
denen kipte çalışmak zorunda kalır. Ototeslim kipinde,
çalıştırdığınız her sorgu veritabanı hareketleri destekliyorsa dolaylı
olarak bir harekettir, desteklemiyorsa değildir. İhtiyacınız toplu
hareketleri kullanmaksa hareketleri ilklendirmek için
PDO::beginTransaction() yöntemini kullanmalısınız. Eğer
kullanmaya çalıştığınız veritabanı toplu hareketleri desteklemiyorsa bir
PDOException istisnası yavrulanır (hata işleme
ayarlarınızdan bağımsız olarak: bu daima bir dizi hata durumundan oluşur).
Bir toplu hareketi ilklendirdikten sonra hareketi başlatmak için
PDO::commit(), hareketler yerine getirilirken
çalıştırdığınız kodun başarı durumuna bağlı olarak hareketleri geri almak
için PDO::rollBack() yöntemini kullanabilirsiniz.
Uyarı
PDO, yalnızca sürücü düzeyinde işlem yeteneklerini denetler. Belirli çalışma
zamanı koşulları hareketlerin kullanılamaz olduğu anlamına geliyorsa, fakat
veritabanı sunucusu bir hareket başlatmak üzere isteği kabul ederse
PDO::beginTransaction() yine de hata vermeksizin
true
döndürecektir.
Buna bir örnek, bir MySQL veritabanında MyISAM tabloları üzerinde hareketleri
kullanmaya çalışmak olurdu.
Bir toplu hareket veritabanına gönderilmişken bir nedenle betiğiniz
sonlanırsa veya bağlantı kapatılmaya çalışılırsa PDO otomatik olarak
hareketleri geri alır. Bu, betiğin beklenmedik durumlarda sonlanmasına karşı
veritabanındaki verilerin tutarsız hale gelmesini önleyecek bir güvenlik
önlemidir. Ancak toplu hareketleri doğrudan siz başlatmadıysanız bir şeyler
zaten yolunda gitmemiş demektir, dolayısıyla verilerinizin güvenliği için
hareketlere başa sarma işlemi uygulanır.
Uyarı
Otomatik başa sarma işlemi sadece toplu hareketler
PDO::beginTransaction() üzerinden ilklendirildiğinde
uygulanır. Bir toplu hareket PDO'sunu başlatan bir sorguyu el yordamıyla
kendiniz başlatırsanız, neler olacağı bilinemez ve yanlış giden bir şeyler
olursa bunlar geri alınamaz.
Örnek 1 - Bir toplu hareket betiğinin çalıştırılması
Aşağıdaki örnekte, yeni bir çalışan için 23 numaralı bir girdi kümesi
oluşturduğumuzu varsayıyoruz. Şahıs için girilen temel bilgilere ilaveten
ücretini de kaydedeceğiz. Bu basit işlemi iki ayrı güncelleme ile yapmak
mümkünse de bu iki deyimi PDO::beginTransaction() ve
PDO::commit() çağrılarının arasına alıp bir sebeple
işlem tamamlanamazsa yapılanların geri alınmasını garantilemiş olacağız.
Eğer bir şeyler yolunda gitmezse catch
kümesi haraket
başladığından beri yapılan işlemleri geri alır ve bir hata iletisi basar.
<?php
try {
$dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2',
array(PDO::ATTR_PERSISTENT => true));
echo "Bağlantı kuruldu\n";
} catch (Exception $e) {
die("Bağlanılamadı: " . $e->getMessage());
}
try {
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->beginTransaction();
$dbh->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')");
$dbh->exec("insert into salarychange (id, amount, changedate)
values (23, 50000, NOW())");
$dbh->commit();
} catch (Exception $e) {
$dbh->rollBack();
echo "İşlem başarısız oldu: " . $e->getMessage();
}
?>
Güncellemeleri birer toplu hareket olarak yapmak zorunda değilsiniz. Almak
istediğiniz veriler için karmaşık sorgular yapabileceğiniz gibi elde
ettiğiniz verilerle başka sorgular ve güncellemeler yapmanızda da mümkündür.
Ancak, bu arada bir toplu hareket işlemi yürütülüyorsa, bu çalışmanın
ortasında kimsenin hiçbir veriyi değiştiremeyeceği garanti altındadır. Toplu
hareketlerle ilgili daha ayrıntılı bilgi için veritabanı sunucunuzun
belgelerine bakınız.