Merhaba arkadaşlar,
Sizlere PostgreSQL ve MySQL’de isolation level ( Read Uncommitted, Read Committed, Repeatable Read, Serializable ) üzerine yaptığım araştırma sonuçları hakkında bilgiler vereceğim. Yazımda bu veritabanlarının farklı senaryolarda verileri kullanıcılara nasıl yansıttığını anlatacağım. Isolation leveller hakkında internette yeterince bilgi olduğu için bunlar hakkında detaylara inmeyeceğim. Isolation leveller transaction işlemlerinde çok önemli. Bir proje geliştirdiğimizde veritabanımızın farklı senaryolarda nasıl tepkiler verdiğini bilmek, veri güvenliği ve kullanıcının hangi veri üzerinde işlem yaptığını bilmesi çok önemli. Birazdan size göstereceğim 3 farklı senaryoda göreceksiniz ki kullanıcı acaba hangi değere sahip veri üzerinde işlem yapıyor?
Senaryolarımız resimde görüldüğü gibi;
Gördüğünüz gibi 3 farklı senaryoda, farklı noktalarda bu iki veritabanı MySQL ve PostgreSQL’in farklı isolation level için nasıl davrandığını göreceğiz.
PostgreSQL için öncelikle iki farklı terminalden giriş yapıyoruz.
Kullandığım komutlar ;
PostgreSQL’e root kullanıcı olarak girmek için :
$ sudo -u postgres psql
Giriş yaptıktan sonra herhangi bir isimle veritabanı oluşturuyoruz. Ben daha önceden oluşturmuştum. Bu veritabanına da student isimli, student_id ve student_name isiminde alanlara sahip bir tablo oluşturdum.
Daha önceden oluşturduğum students veritabanına bağlanmak için :
postgres=# \connect students
Veritabanında bulunan tabloları görüntülemek için :
students=# \dt
Tabloda bulunan verileri görüntülemek için :
students=# SELECT * FROM student;
Ekran görüntüsü :
Güncel transaction isolation level’i öğrenmek için :
students=# select current_setting('transaction_isolation');
Oturumdaki transaction isolation level’i değiştirmek için :
students=# SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;
Sadece bir transaction da isolation level’i değiştirmek için :
students=# SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
A noktası için senaryomuzu uygulayabilmek için iki terminalde isolation levelleri aynı olarak ayarladıktan sonra iki terminalde BEGIN komutu ile transaction başlatıyoruz. Her iki oturum için transaction başlattıktan sonra 1. senaryo daki gibi oturumun birinde güncelleme yapıyoruz ve ardından diğerinde okuma yapıyoruz. Aşşağıdaki resimde gördüğünüz gibi read committed için bir transaction da güncelleme yaptıktan sonra diğer transaction da okuma yaptığınızda transaction sonlandırılmadığı için eski değeri görüyoruz.
Isolation level güncelleme :
Aynı senaryo read uncommitted için de okuma yapıldığında read committed ile aynı sonuç elde edilir. Fakat aynı işlem MySQL de yapıldığında read uncommitted için güncellenmiş veri okunur. Aşşağıdaki şekilde terminaller alt alta yer almaktadır. Daha önce anlattığım gibi her ikisinde önce transactionlar BEGIN komutu ile başlatılır daha sonra altaki terminalden güncelleme yapılır. Bu işlemden sonra üstteki terminalden okuma yapılır.
Bu şekilde veritabanımızın farklı senaryolarda nasıl davrandığını test edebiliriz. Bu işlem MySQL’de de aynı şekilde terminalden yapılabiliyor. MySQL için isolation’ı öğrenme ve değiştirme komutları farklı. Ben bu testleri daha önceden yapmıştım. Sonuçları alt tarafta paylaştım.
| PostgreSQL | MySQL --------------------------------------------------------------------------------------------------------- A Noktası READ UNCOMMITTED | Eski değeri okur | Yeni değeri okur READ COMMITTED | Eski değeri okur | Eski değeri okur REPEATABLE READ | Eski değeri okur | Yeni değeri okur SERIALIZABLE | Eski değeri okur | Transaction 2 için bekler ve bittiğinde eski değeri okur B Noktası READ UNCOMMITTED | Veri güncellenir | Veri güncellenir READ COMMITTED | Veri güncellenir | Veri güncellenir REPEATABLE READ | Veri güncellenir | Veri güncellenir SERIALIZABLE | Veri güncellenir | Transaction 1 için bekler C Noktası READ UNCOMMITTED | Eski değeri okur | Yeni değeri okur READ COMMITTED | Eski değeri okur | Eski değeri okur REPEATABLE READ | Eski değeri okur | Eski değeri okur SERIALIZABLE | Eski değeri okur | Eski değeri okur D Noktası READ UNCOMMITTED | Yeni değeri okur | Yeni değeri okur READ COMMITTED | Yeni değeri okur | Yeni değeri okur REPEATABLE READ | Eski değeri okur | Eski değeri okur SERIALIZABLE | Eski değeri okur | Eski değeri okur E Noktası READ UNCOMMITTED | Verileri gösterir | Verileri gösterir READ COMMITTED | Verileri gösterir | Verileri gösterir REPEATABLE READ | Verileri gösterir | Verileri gösterir SERIALIZABLE | Verileri gösterir | Verileri gösterir F Noktası READ UNCOMMITTED | Veri güncellenir | Veri güncellenir READ COMMITTED | Veri güncellenir | Veri güncellenir REPEATABLE READ | Veri güncellenir | Veri güncellenir SERIALIZABLE | Veri güncellenir | Transaction 2 için bekler G Noktası READ UNCOMMITTED | Transaction 1 için bekler | Transaction 1 için bekler READ COMMITTED | Transaction 1 için bekler | Transaction 1 için bekler REPEATABLE READ | Transaction 1 için bekler | Transaction 1 için bekler SERIALIZABLE | Transaction 1 için bekler | Execption: ERROR 1213 (40001): Deadlock found when trying to get lock;
Üstteki sonuçlardan gördüğümüz gibi PostgreSQL, MySQL’e göre daha kararlı bir yapıya sahip ve ölüm kilidi (deadlock) durumu oluşmuyor. Benim burda araştırmasını yaptığım 3 farklı senaryo daha değişik biçimlerde verilerin silinmesi gibi durumlar içinde incelemesi yapılabilir.
Teşekkürler..
Kolay gelsin…