Home / MAKALELER / Veri Tabanı / SQL Server’da Transaction Kullanımı

SQL Server’da Transaction Kullanımı

Veritabanı sistemlerini yüzeysel kullanan geliştiriciler için çok basit gelen işlemler aslında mimari olarak geri planda bir çok iş sürecinin doğru yürütülmesiyle meydana gelmektedir. Bu iş süreçleri veritabanı motoru tarafından yönetilir. Ancak, depoladığımız veriyle ilgili işlemlerin bütünlüğü tamamen bize, yani geliştiriciye aittir.

Örneğin, birbiriyle ilişkili bir sorgu yapısı var ve biz bu kodların tamamının doğru çalışması halinde başarılı bir işlem gerçekleştirmiş olacak isek, bu durumda herhangi bir parça işlemin başarısız olması halinde diğer yapılan tüm işlemlerin geri alınması mantıklı olacaktır. Bu işleme en gerçekçi ve bilinen örnek bankacılık işlemleri gösterilebilir. Bir havale yapmak için gerekli tüm işlemleri yaptınız ve X hesabından Y hesabına 10 tl para göndereceksiniz. Bu işlemin programsal olarak yapılabilmesi için sizin hesabınızdaki bakiyenin UPDATE ile güncellenerek azaltılması, gönderilen hesabın bakiyesinin de UPDATE ile güncellenerek alınan miktar kadar artırılması gerekir. Ancak teknolojide herşey doğru gitmeyebilir. Bu işlemler sırasında herhangi bir hata olursa sizin hesabınızdan 10 tl düşülecek, ancak karşı tarafın hesabı güncellenerek bakiye artırımı gerçekleşmeyebilir.

Veritabanı mimarisinde bu tür iş süreci(transaction) gerektiğinde uyulması gereken prensibe ACID (Atomicity, Consistency, Isolation, Durability) denir.

Şimdi ACID’i sırasıyla inceleyelim.

Bölünemezlik(Atomicity)

Transaction işleminin ana özelliği olarak açıkladığımız bölünemezlik prensibini yansıtır. Bir transaction bloğu yarım kalamaz. Yarım kalan transaction bloğu veri tutarsızlığına neden olur. Ya tüm işlemler gerçekleştirilir, ya da transaction başlangıcına geri döner. Yani transaction’ın gerçekleştirdiği tüm değişiklikler geri alınarak gerçekleşmeden önceki haline döner.

Tutarlılık(Consistency)

Bölünemezlik kuralının alt yapısını oluşturduğu bir kuraldır. Transaction veri tutarlılığı sağlamalıdır. Yani bir transaction içerisinde güncelleme işlemi gerçekleştiyse ve ya kalan tüm işlemler de gerçekleşmeli ya da güncelle işlemi de geri alınmalıdır. Bu veri tutarlılığı açısından çok önemlidir.

İzolasyon(Isolation)

Her transaction veritabanı için bir istek paketidir. Bir istek paketi (transaction) tarafından gerçekleştirilen değişiklikler tamamlanmadan bir başka transaction tarafından görülememelidir. Her transaction ayrı olarak işlenmelidir. Transaction’ın tüm işlemleri gerçekleştikten sonra bir başka transaction tarafından görülebilmelidir.

Dayanıklılık (Durability)

Transaction’lar veri üzerinde karmaşık işlemler gerçekleştirebilir. Bu işlemlerin bütününü güvence altına almak için transaction hatalara karşı dayanıklı olmalıdır. SQL Server’da meydana gelebilecek sistem sorunu, elektrik kesilmesi, işletim sisteminden ya da farklı yazılımlardan kaynaklanabilecek hatalara karşı hazırlıklı ve dayanıklı olmalıdır.

Bilgisayar bilimlerinde imkansız diye bir şey yoktur. Bir sistemin hata vermesi yüzlerce sebebe bağlı olabilir. Örneğin; geçtiğimiz yıllarda büyük bir GSM operatörünün veri merkezinin bulunduğu binaya sel basması sonucu veri kaybı yaşamışlardı. Bu durum olasılığı düşük gibi görünebilir. Ancak bahsi edilen konu önemli veriler olunca, hesaplanması gereken olasılıkların sınırı yoktur. Tüm hata olasılıklarına karşı dayanıklı bir sistem geliştirilmelidir.

Transactıon İfadeleri

Transaction yönetimi için kullanılan dört farklı ifade vardır. Bu ifadeler ile transaction başlatılabilir (BEGIN), işlemler geri alınabilir (ROLLBACK), transaction bitirilebilir (COMMIT) ya da kayıt noktaları (SAVE) oluşturulabilir.

Transactıon’ı Başlatmak: BEGIN TRAN

Transaction’ın başlangıcını belirtir. Bu kısımdan sonraki tüm işlemler transaction’ın bir parçasıdır. İşlem sırasında oluşabilecek olası sorunlarda geri alma ya da transaction’ın sonlandırılması gerçekleştirilebilir.

Söz Dizimi:

BEGIN TRAN[SACTION] [transaction_ismi | @transaction_degiskeni]

Transactıon’ı Tamamlamak: COMMIT TRAN

Transaction’ın tamamlandığını ve gerçekleştirilen transaction işlemlerinin kalıcı olarak veritabanına yansıtılması için kullanılır. Transaction tarafından etkilenen tüm değişiklikler, işlemlerin tamamı gerçekleşmese bile, bu işlemden sonra kalıcı hale gelir.
COMMIT işleminden sonra gerçekleşen değişikliklerin geri alınması için, bu işlemleri geri alacak yeni bir transaction oluşturulmalıdır. Örneğin; bir transaction ile, nümerik bir sütun üzerinde 10 birim azaltma işlemi yapıldı ise, bu işlemi geri almak için aynı sütun üzerinde 10 birim artırma işlemi yapacak yeni bir transaction oluşturulmalıdır.

Söz Dizimi:

COMMIT TRAN[SACTION] [transaction_ismi | @transaction_degiskeni]

Transactıon’ı Geri Almak : ROLLBACK TRAN

Transaction’ın gerçekleştirdiği tüm işlemleri geri almak için kullanılır. Yani, yapılan tüm işlemler transaction’ın başlangıcındaki haline geri döner. Verilerdeki değişikliklerin anında kalıcı olarak veritabanına yansıtılmadığını belirtmiştik. ROLLBACK ile gerçekleştirilen tüm işlemler geriye alınarak transaction sonucunun tutarlılığı garanti edilir.
ROLLBACK işlemi, oluşturduğunuz transaction mimarisine bağlı olarak, kayıt noktalarına (save points) geri dönüş için de kullanılabilir.

Söz Dizimi:

ROLLBACK TRAN[SACTION] [transaction_ismi | kayit_noktasi_ismi | @transaction_degiskeni | @kayit_noktasi_degiskeni]

Sabitleme Noktaları: SAVE TRAN

ROLLBACK işlemi transaction’da en başa dönmek için kullanılır. Bazen de belirli bir noktaya kadar gerçekleşen işlemlerin geçerli kalması istenebilir. Bu işlemlerden sonra gerçekleşecek işlemler için ROLLBACK’e ihtiyaç duyulabilir. Sabitleme noktaları oluşturulması, transaction içerisinde en başa dönmek yerine, belirlenen bir işlem noktasına dönmek için kullanılır

Söz Dizimi:

SAVE TRAN[SACTION] [ kayit_noktasi_ismi | @kayit_noktasi_degiskeni ]

Transactıon Oluşturmak

Transaction işlemleri için en uygun örnekler bankacılık ve gsm operatörlerinin veritabanı işlemleridir. Karmaşık ve bir çok iş parçacığı ile gerçekleşen sayısız işlemden oluşan bu tür uygulamalarda iş bloklarının doğru planlanması ve kullanılması önemlidir.
Bir banka veritabanında kullanıcı hesaplarını tutan ve farklı iki banka hesabı arasında havale işlemini gerçekleştirmek için bir uygulama oluşturalım.

Banka müşterilerinin hesap bilgilerini tutan basit bir tablo oluşturalım.

CREATE TABLE Accounts(
    AccountID   CHAR(10) PRIMARY KEY NOT NULL,
    FirstName   VARCHAR(50),
    LastName    VARCHAR(50),
    Branch  INT,
    Balance MONEY
);

AccountID : Hesap sahibine özel benzersiz değer.
FirstName : Hesap sahibinin adı.
LastName : Hesap sahibinin soyadı.
Branch : Şube kodu.
Balance : Hesap bakiyesi.

INSERT INTO Accounts
VALUES('0000065127','Cihan','Özhan', 489, 10000),
      ('0000064219','Ali','Veli', 489, 500),
      ('0000068233','Hasan','Hseyin', 252, 5844);

Sorgulama için gerekli veriyi eklediğimize göre, artık ilgili prosedürümüzü oluşturarak transaction’ımızı yönetmeye başlayabiliriz.

CREATE PROC sp_MoneyTransfer(
    @PurchaserID    CHAR(10),
    @SenderID       CHAR(10),
    @Amount         MONEY,
    @retVal         INT OUT
)
AS
BEGIN
    DECLARE @inControl MONEY;
    SELECT @inControl = Balance FROM Accounts WHERE AccountID = @SenderID;
    IF @inControl >= @Amount
    BEGIN
        BEGIN TRANSACTION
            UPDATE Accounts
            SET Balance = Balance - @Amount
            WHERE AccountID = @SenderID
        IF @@ERROR  0
        ROLLBACK
            UPDATE Accounts
            SET Balance = Balance + @Amount
            WHERE AccountID = @PurchaserID
        IF @@ERROR  0
        ROLLBACK
        COMMIT
    END
    ELSE
    BEGIN
        SET @retVal = -1;
        RETURN @retVal;
    END
END;

Prosedürün aldığı parametreleri açıklamak gerekirse;

PurchaserID : Alıcı hesabın ID’si
SenderID : Gönderen hesabın ID’si
Amount : Gönderilecek tutar
retVal : Prosedür içerisinden geriye değer dönmeyi sağlayan OUT parametre. İşlem başarısız olursa -1 değeri döndürecek.

Şimdi, Cihan Özhan’ın Ali Veli’ye 500 tl göndermesini sağlayacak prosedür çağrımını yapalım.

DECLARE @rVal INT;
EXEC sp_MoneyTransfer '0000064219','0000065127',500, @rVal out;
SELECT @rVal;

Bu tür prosedürlerde bir çok işlem kontrol edilir. Ancak biz sadece gönderen kişinin hesabında göndermek istediği kadar miktar olup olmadığını kontrol ettik.

İyi çalışmalar.
Cihan Özhan

About Cihan Özhan

Yazılım, veri bilimi ve veritabanı üzerine araştırmalar yapan bir yazılım teknolojileri araştırmacısıdır. - Oracle PL/SQL Programlama eğitim setini hazırladım. - İleri Seviye T-SQL Programlama kitabının yazarıyım. - C#, GO, WPF, WCF, Web API gibi bir çok teknolojilerde eğitim içerikleri hazırladım. Kısaca hakkımda bilgisi ve ürettiğim eğitsel materyaller için; www.cihanozhan.com

İlginizi Çekebilir

AWR ( Automatic Workload Repository )

Merhaba, Bu yazıda AWR ( Automatic Workload Repository )  Oracle Database Üzerinde sıklıkla kontrol ettiğimiz AWR raporunu …

Bir Cevap Yazın