REDIS TRANSACTION YÖNETİMİ
Çoğu database gibi redis de transaction yönetimini destekler. Transaction kullanarak, birden fazla redis commandini gruplayabilir, böylece bu commandlerin araya herhangi bir başka komut girmeden bir kerede hepsinin çalışacağını veya çalışmayacağını garanti edebilirsiniz.
Rediste transcation’u başlatmak için multi komutu kullanılır. Multi komutu yazıldığı andan itibaren, yazılan komutlar çalıştırılmaz ve queue’ya atılır. Her ne zaman ki exec komutu yazılır ve çalıştırılır o zaman transaction içerisindeki komutlar çalıştırılır. Discard komutu ile de çalışan transaction içerisindeki tüm komutlar silinip transaction durdurulabilir. Ancak redis transcationu ile ilgili bilinmesi gereken en önemli noktalardan biri rollback olmamasıdır. Bunun anlamı transcation içerisindeki komutlardan biri fail olursa kalanlar çalışmaya devam eder.
Redis üzerinde transcation yönetimini netleştirmek için ufak bir örnekle devam edelim. Transactionun anlatıldığı her yerde bahsedilen klasik bankacılık örneği üzerinden gidelim. Bir banka hesabından 50 TL yi başka bir banka hesabına geçireceğimizi varsayalım. Bir banka hesabındaki paranın azalıp diğerinin artması gerekecek. Mantıken bu iki işlem arasına herhangi bir işlemin girmesi söz konusu olmamalı yani bir hesaptan paranın azalıp buna rağmen diğer hesaba paranın geçmemesi gibi bir durum yaşanmamalı.
- account-a ve account-b adında 2 adet hesabımız ve bunların içinde 100 ve 200tl bakiye olduğunu varsayalım.
set account-a 100 set account-b 200
- Hesaplarımızı tanımladığımıza göre artık transcation işlemini tanımlayalım. Bunun için multi komutunu yazarak başlayalım. Multi komutundan sonra yazılan her komut transcation execute edildiği anda çalıştırılmak için queue’ya atılacaktır. Daha sonra account-a’dan 50tl azaltıp, account-b’yi 50 tl artıran kodları yazalım. Ve en sonunda transcationu başlatacak komut exec.
multi incrby account-a -50 incrby account-b 50 exec
- Tüm işlem bu kadar. Account-a’dan 50 tl azaldı. Account-b’ye 50tl geçti. Eğer exec yerine discard yazmış olsaydık, transactiondaki tüm queue boşaltılır komut kalmazdı.
Bazı durumlarda biz daha transactionu başlatmadan önce, transaction içerisinde kullanılan keyler üzerinde değişiklik yapılmamış olmasını garanti etmek isteyebiliriz. Örneğin, biz A hesabından B hesabına 100 tl geçirecek bir transaction hazırladık. Biz bu transactionu hazırlarken A hesabında 100tl B hesabında da 100tl bakiye olduğunu varsayalım. Biz tam transcationu çalıştırmadan önce başka bir client A hesabında bir değişiklik yapmış olabilir. Bakiyeyi sıfırlamış olabilir. Bu gibi durumlarda watch komutu ile key’i izleyebiliriz. Watch ile izlenen keyde herhangi bir değişiklik yapıldığı an transcation çalıştırılmaya çalışıldığı an null sonucunu döner ve çalışmaz.
watch account-a
TRANSACTION HATA YÖNETİMİ
Redis transcationunda ya tüm komutlar çalıştırılır ya da hiç biri çalıştırılmaz. Yani redis transactionları atomictir. Peki rediste transaction esnasında hatayla karşılaşma durumları nelerdir ve redis bunları nasıl tepki verir biraz da bunları inceleyelim.
Rediste transaction sırasında karşılaşılması muhtemel 2 hata tipi vardır.
- Komut transaction içerisine syntax olarak yanlış yazılabilir. Böyle bir durumda user daha hatalı komutu yazdığında hatayla karşılaşır ancak bunun akabininde tekrar doğru komutu yazıp transactionu oluşturmaya devam edip exec komutunu yazdığı an transactionun içerisinde önceden yazılan hatalı komut yüzünden transactionun “EXECABORT Transaction discarded because of previous errors.” hata mesajı ile execute olmadığını görecektir.
- İkinci olası hata durumu, exec komutu çalıştırıldıktan sonra karşılaşılabilecek hatalardır. Örneğin, syntaxi doğru ama çalıştırılırken hata alınacak bir komut bu tip bir hataya sebebiyet verebilir. Burada bilinmesi gereken önemli husus, komutlardan biri hatalı olsa dahi diğer komutlar çalışmaya devam eder.
Redis Neden Rollback’i desteklemez?
İsterseniz bunu redis kendi sitesinde nasıl açıklamış ona bakalım. Aşağıda redisin sitesinden aldığım iki madde bulunmakta
- Redis komutları, yalnızca yanlış bir sözdizimi (ve komut sıralaması sırasında sorun algılanamazsa) veya yanlış veri türünü tutan tuşlara karşı çağrılırsa başarısız olabilir: bu, pratik terimlerle başarısız bir komutun programlama hatalarının sonucu olduğu anlamına gelir. ve production sırasında değil, geliştirme sırasında algılanması muhtemel bir hata türüdür.
- Redis dahili olarak basitleştirilmiştir ve daha hızlıdır, çünkü geri alma özelliği gerekmez.
Redisin bakış açısına göre redis queryleri sırasında hatalar olabilir ancak genel olarak geri alma işlemi sizi programlama işlemlerinden kurtarmaz. Örneğin bir sorgu bir key’i 1 yerine 2 artırıyorsa veya yanlış bir anahtarı artıyorsa aslında burda geri alma mekanizması yardımcı olamaz.
Hiç kimsenin programcıyı ana hatalarından kurtaramayacağı ve redis komutunun başarısız olması için gereken türden hatalar yapma olasılığının düşük olduğunu düşünürsek, daha basit ve daha hızlı olan, hatalarda geri dönüşleri yani rollbacki desteklememe kararı almış.