SQL Server’da Transaction Kullanımı ve Yönetimi

Cihan Ozhan
4 min readSep 15, 2018

--

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.

Kaynak 1 : http://www.cihanozhan.com/sql-serverda-transaction-kullanimi-yonetimi

Kaynak 2 : Yazılımcılar İçin İleri Seviye T-SQL Programlama

Kaynak 3 : https://www.linkedin.com/pulse/sql-serverda-transaction-kullan%C4%B1m%C4%B1-ve-y%C3%B6netimi-cihan-%C3%B6zhan/

--

--