International PHP Conference Berlin 2023

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_ERRMODEPDO::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.

add a note

User Contributed Notes 3 notes

up
5
harl at gmail dot com
4 years ago
Some DBMSs allow DDL (table creation/alteration) within transactions, some do not. Asking "Does my DBMS allow DDL within transactions without forcing a commit?" gives the following example answers:

CUBRID: Yes
DB2 UDB: Yes
Firebird: Yes
Informix: Yes
MySQL: No
Oracle: No (although schema upgrades can be rolled out using "edition-based redefinition")
PostgreSQL: Yes
SQLite: Yes
SQL Server: Sometimes, depending on isolation level, type of command, etc.
Sybase: Yes
up
1
pasamio at gmail dot com
10 years ago
Typically data definition language clauses (DDL) will trigger the database engine to automatically commit:
http://dev.mysql.com/doc/refman/5.0/en/implicit-commit.html

Many other databases (e.g. Oracle) will implicitly commit before and after running DDL statements.
up
0
hooby404 at gmail dot com
5 months ago
> You're not limited to making updates in a transaction; you can also issue complex
> queries to extract data, and possibly use that information to build up more updates
> and queries; while the transaction is active, you are guaranteed that no one else can
> make changes while you are in the middle of your work. For further reading on
> transactions, refer to the documentation provided by your database server.

This only holds true if you specifically do "SELECT .... FOR UPDATE".

Without the "FOR UPDATE" part, when two transactions run at the same time, the second transaction could change a value AFTER the first transaction read it, but BEFORE the first transaction used it for updates.

Without the "FOR UPDATE" part you are absolutely NOT GUARANTEED that no one else can make changes while you are in the middle of your work.
To Top