- Konu sahibi
- #1
MySQL transaction nedir?
MySQL transaction, bir veya daha fazla SQL işlemini tek bir bütün olarak yürütme yöntemidir. İşlemlerin tamamı başarılı olursa
COMMIT ile kalıcı hâle getirilir; hata veya iş kuralı ihlalinde uygulama ROLLBACK ile onaylanmamış işlemsel değişiklikleri geri alabilir. Her SQL hatası bütün transaction’ı kendiliğinden geri almaz. Böylece özellikle para transferi, stok düşme ve sipariş oluşturma gibi birden fazla tabloyu etkileyen işlemlerde yarım kalmış veriler engellenir.Transaction nasıl çalışır?
Bir transaction genellikle şu akışa sahiptir:
-
START TRANSACTIONveyaBEGINile işlem bloğunu başlatın. - Gerekli
INSERT,UPDATEveDELETEsorgularını çalıştırın. - Tüm sorgular beklenen sonucu verdiyse
COMMITçalıştırın. - Bir sorgu başarısız olduysa ya da iş kuralı sağlanmadıysa
ROLLBACKçalıştırın.
Transaction'ın güvenilir çalışması için etkilenen tabloların transaction destekleyen bir storage engine kullanması gerekir. MySQL'de yaygın tercih
InnoDB'dir. Transaction desteklemeyen bir tabloya yapılan değişiklik, aynı blok içinde yazılmış olsa bile rollback ile geri alınamayabilir.Somut örnek: değişikliği geri alma
Aşağıdaki kurgu yalnız yeni bir deneme veritabanı içindir. Tabloyu transaction başlamadan oluşturun; aynı adlı gerçek tablo üzerinde denemeyin. Örnek InnoDB kullanır ve başka bir oturumun bu deneme satırlarını değiştirmediğini varsayar.
Kod:
CREATE TABLE transaction_demo (
id INT PRIMARY KEY,
adet INT NOT NULL
) ENGINE=InnoDB;
INSERT INTO transaction_demo VALUES (1, 10), (2, 20);
START TRANSACTION;
UPDATE transaction_demo SET adet = adet - 1 WHERE id = 1;
UPDATE transaction_demo SET adet = adet + 1 WHERE id = 2;
SELECT id, adet FROM transaction_demo ORDER BY id;
ROLLBACK;
SELECT id, adet FROM transaction_demo ORDER BY id;
İlk SELECT aynı oturumda 9 ve21 değerlerini; ROLLBACK sonrasındaki SELECT ise10 ve20 değerlerini göstermelidir. Değişikliği kalıcılaştırmayı denemek için iki UPDATE’i yeni bir START TRANSACTION içinde yeniden çalıştırın ve bu kez COMMIT seçin. Sonraki sorguda9 ve21 kalır.
Bu örnek otomatik hata yönetimi içermez. Gerçek uygulamada ilk sorgu hata verirse veya beklenen satır sayısını etkilemezse ikinci sorguya ve COMMIT’e devam edilmemelidir. Bağlantı sürücüsüyle her adımı denetleyip başarısız durumda ROLLBACK seçin. Metin içindeki açıklama satırı, çalışan bir koşul kontrolünün yerine geçmez.
InnoDB’de bazı hatalar yalnız ilgili ifadeyi geri alırken deadlock bütün transaction’ı geri alabilir. Uygulama hata türünü ve işlem durumunu bilmeli; yeniden deneme gerekiyorsa mükerrer dış etki oluşturmayan, kontrollü bir akış kurmalıdır.
Autocommit ve transaction seçimi
MySQL bağlantılarında autocommit etkinse tek bir
INSERT, UPDATE veya DELETE sorgusu çoğunlukla kendi transaction'ı içinde otomatik olarak onaylanır. Birden fazla sorgunun birlikte başarılı olması gerekiyorsa açıkça START TRANSACTION kullanın.Kararı şu şekilde verebilirsiniz:
| Durum | Uygun yaklaşım | Neden |
|---|---|---|
| Tek ve bağımsız bir kayıt değişikliği | Autocommit yeterli olabilir | Ek sorgularla birlikte korunması gerekmiyorsa blok oluşturmak şart değildir |
| Birden fazla tablo veya sorgu | Açık transaction kullanın | Tüm değişiklikler birlikte onaylanır veya geri alınır |
| İş kuralı sağlanmadı | ROLLBACK uygulayın | Kısmi değişikliği kalıcılaştırmaz |
Transaction'ı gereğinden uzun açık bırakmayın. Uzun süren transaction'lar kilitlerin daha uzun tutulmasına, diğer sorguların beklemesine ve geri alınacak değişiklik miktarının büyümesine neden olabilir. İşlem tamamlandıktan sonra mutlaka
COMMIT veya ROLLBACK ile kapatın.Sık yapılan hatalar
- Tablo engine'inin transaction destekleyip desteklemediğini kontrol etmemek.
- Bir sorgu başarısız olduğunda uygulama tarafında yine de
COMMITçalıştırmak. -
UPDATEsonucundaki etkilenen satır sayısını kontrol etmemek. - Transaction içinde kullanıcıdan yanıt beklemek veya uzun süren dış servis çağrıları yapmak.
- Bağlantı havuzuna dönen bağlantıda açık transaction bırakmak. Bağlantı yeniden kullanılmadan önce işlem durumu uygulamanın bağlantı yönetimi tarafından temizlenmelidir.
İlk uygulama adımı olarak ilgili tabloların transaction destekleyen engine kullandığını doğrulayın, ardından çoklu sorgu akışını açıkça
START TRANSACTION ve COMMIT/ROLLBACK çiftiyle kurun. Hata senaryolarını da test ederek hiçbir sorgu başarısızken kısmi değişikliğin kalıcı olmadığını kontrol edin.Sık sorulan sorular
Transaction içinde ikinci START TRANSACTION iç içe işlem başlatır mı?
Hayır. MySQL’de transaction’lar bu şekilde iç içe kurulmaz; yeni START TRANSACTION mevcut işlemi örtük olarak commit edebilir. Kısmi geri dönüş noktası gerekiyorsa uygun SAVEPOINT yaklaşımını değerlendirin; bağlantıdaki işlem durumunu bilmeksizin yeni başlangıç komutu göndermeyin.
ROLLBACK tablo oluşturmayı veya değiştirmeyi de geri alır mı?
Genel olarak bu güvenceyi vermez. CREATE TABLE ve ALTER TABLE gibi birçok DDL ifadesi örtük commit oluşturur. Veritabanı motorunun işlemi kendi içinde atomik yapması, uygulamanın ROLLBACK komutuyla onu geri alabileceği anlamına gelmez. Şema değişikliğini veri transaction’ının içine koyarak geri dönüş planı kurmayın.