Muazzez KONUKLU

Cumartesi, Şubat 03, 2007

SQL TRIGGERS


Triggers(Tetikleyiciler)

Trigger'lar, bir tablo üstünde tanımlanabilen ve TRANSACTION'dan sonra çalışabilen programlanabilir öğelerdir. Daha açıklayıcı olarak, kayıt eklendiğinde, silindiğinde veya değiştirildiğinde otomatik olarak devreye giren özel bir çeşit SP'lerdir

Triggers(Tetikleyiciler), aslında özel bir Stored Procedure’dür. SP’lerden farkı, bir tablo üstünde UPDATE ,INSERT,DELETE komutları ile bir işlem yapılmak istendiğinde, ilk olarak bu SP’lere bakılması ve gerekli ise çalıştırılmasıdır.

Trigger'lar izin verilmeyen ya da tutarsızlığa neden olacak işlemleri engelleyerek veri bütünlüğünün korunmasına yardımcı olurlar.
Triggerlar genellikle değişik tablolar üzerinde bulunan ve birbirleri arasında mantıksal ilişkilere sahip verilerin tutarlılığını sağlamak üzere oluşturulurlar. İhtiyaca göre uygulamanın getirdiği bazı kuralları kontrol etmek için de kullanılabilirler.

UYARI:Recursive olarak çalışmazlar. Yani bir tablonun herhangi bir sütununda yapılan değişiklik üzerine bir trigger çalışıp aynı tablonun başka bir sütünunda değişikliğe neden oluyorsa ikinci yapılan değişiklik trigger için tetiklenmeye neden olmaz. Kısaca update triggerı tekrar tekrar çalışmaz, yalnızca bir kez çalışır.

Genel kullanımı:

CREATE TRIGGER trigger_adi
ON tablo_adi
FOR INSERT [,UPDATE,DELETE]
AS
SQL ifadesi


Şeklindedir.

Trigger’lerin bir UPDATE, INSERT veya DELETE komutuna cevap olarak çalışması, Transaction mantığı ile aynıdır.

Bir tablo için TRIGGER tanımlı ise INSERT, DELETE veya UPDATE işlemi başlamadan hemen önce bir Transaction başlatılır.

INSERT, DELETE veya UPDATE komutu yerine getirilir.

Trigger çağrılır ve içindeki SQL ifadesi çalıştırılır.

Trigger işlemi onaylarsa geçerli kılar veya onaylamaz ve geçersiz bulur. Transaction geri alınır. (ROLLBACK TRANSACTION).

Bir Trigger oluştururken şu durumlara dikkat etmek gerekir:

View ya da geçici tablolar üzerinde oluşturulamazlar. Fakat bunlara referans içerebilirler.

Çalıştıktan sonra bir kullanıcıya değer kümesi döndüremezler. Dolayısıyla
SELECT ifadesi dahil edileceği zaman dikkatli olunmalıdır.

Veri bütünlüğünü, farklı tablolardan birbirine referans yapan verilerin tutarlılığını sağlamak için ve uygulamanın ihtiyacına göre bazı kuralları tanımlamak üzere kullanılabilirler. Ancak zorlayıcılarla düzenlenebilecek trigger kullanmamak daha faydalıdır.

İstenirse syscomments tablosunda şifrelenmiş tekilde saklanabilirler.

CREATE, DROP, ALTER TABLE, ALTER DATABASE, SELECT INTO gibi ifadeler trigger içinde kullanılmazlar.


Trigger OluŞturmak

Enterprise Manager kullarak tetikleyici oluşturmak istersek, bunun için;
Enterprise Manager'i başlatip.

Trigger oluşturmak istediğiniz tabloya sağ tıklayarak All Tasks başlığından Manage Triggers seçeneği secilir. Açılan pencere tetikleyici oluşturmak ve düzenlemek için bir arabirim sunar.




Bu arabirim bize tetikleyici için bir şablon sunar. Köşeli parantezlerin ( [ ] ) içindeki değerleri değiştirerek istediğimiz işlevi yerine getrirecek tetikleyiciyi oluşturabiliriz.

İlk değişkenimizi ( [TRIGGER NAME] ) tetikleyicimize vermek istediğimiz isim ile değiştirin. İkinci değişken, tetikleyicinin hangi tablo üzerinde oluşturulacağını belirler.

Trigger oluşturmak için sağ tıkladığımız tablonun adı (resimde [dbo].[musteri] olan kısım) varsayılan olarak şablona yazılmış durumda gelecektir.

For ifadesinden sonraki kısım tetikleyicinin hangi işlemlerden sonra çalışacağını belirler.

As ifadesinden hemen sonra ise tetikleyicinin ne iş yapacağı belirlenir.


Örnek:Bir tablodaki kayıtlar üstünde değişiklik yapıldığında kaç kaydı etkilediğini yazan bir trigger oluşturalım:

CREATE TRIGGER trAffectedRows
ON odunc
FOR INSERT, UPDATE,DELETE
AS
raiserror ("%d kayıt üzerinde değişiklik yapılmıştır",0,1,@@rowcount)
RETURN

EK BILGI --> RAISERROR: Hata mesajları, SQL Server'in kendi iç hatalarını da ifade etmek için kullandığı mesajlardır. Bunların bir listesini almak için, SQL Server'de şu sorguyu çalıştırabilirsiniz.

SELECT * FROM master.dbo.sysmesseges
Hata mesajları master veritabanında tutulmaktadır. Ek bir hata mesajı tanımını buraya ekleyebilirsiniz.

Bir kullanıcı tanımlı hata mesajını kullanmak iki aşamada ele alınabilir.
Hata mesajının sysmessages tablosuna eklenmesi
İlgili durum oluştuğu anda, hata mesajının RAISERROR ile ilan edilmesi.
raiserror ("%d kayıt üzerinde değişiklik yapılmıştır",0,1,@@rowcount)


Burada, RAISERROR fonksiyonunun nasıl kullanıldığına dikkat etmek gerekir. Tirnak icinde yazilan yazi ekrana gelecek olan hata mesajidir. Birinci parametre olarak bir hata sistem kodudur. İkinci parametre bu hatanın oluşumundaki kritiklik seviyesidir. Son parametre ise, bu hatanın iç işleyişte nasıl ele alınacağı ile ilgili bir parametredir.


Eklenen-Silinen Kayıtlar

Triggerlar çalıştığı zaman Inserted ve Deleted tablolarını kullanırlar. Bu tabloların her ikisi de ana tabloyla yani triggerın tetiklendiği tabloyla eşdeğer alanlara sahiptirler. Bu tablolar, mantıksal tablo şeklinde RAM' de bulunurlar.

Ana tabloya bir kayıt eklendiği zaman bu kayıt aynı zamanda inserted tablosuna da eklenir. İhtiyacımız olduğu zaman yeni eklenen değerlere bu tablodan ulaşarak, bu bilgileri tutmak maksadıyla değişken tanımlamak zorunda kalmaktan kurtuluruz.

Tablodan bir kayıt silindiğinde silinen kayıt deleted tablosunda saklanır.
Update işlemi ise delete ve hemen ardından yapılmış bir insert işlemi olarak ele alınır. Bir kayıt update edildiğinde orjinal kayıt deleted tablosuna işlenir, değişen kayıt da inserted tablosunda (ve ana tabloda) saklanır.

Trigger’lere dışarıdan parametre yollayamayız. Ancak, INSERTED ve DELETED tabloları sayesinde kısıtlı da olsa, son işlemden etkilenmekte olan kayıtları tespit edebiliriz.
Örnek:
Kitaplardan bir kısmı, ödünç verildiği ve gelmediği halde bir başkasına daha ödünç verilmiş görünebiliyor. Böyle bir hata yapılmasını kökten çözmek için bir Trigger oluşturalım:

CREATE TRIGGER tr_oduncKontrol
ON odunc
FOR INSERT,UPDATE
AS
IF(SELECT COUNT(kitapNo) FROM odunc,inserted WHERE geldiMi=0 AND inserted.kitapNo=odunc.KitapNo)>1
BEGIN
PRINT ‘disaridaki kitab bir baskasina veremezsiniz…’
ROLLBACK TRANSACTION
END

Bu örnekte verilen durumun içerisinden foreign key zorlayıcısı ile çıkılamayacağına dikkat edin. Trigger’ler, uygulamaya özgü kuralları veritabanı sisteminin bir parçası olarak tayin etmek istenildiğinde de kullanılır.

Trigger ve Stored Procedure' lerı karşılaştırırsak, her ikisi de önceden derlenmiş SQL ifadeleri olduğundan hemen hemen aynı hızda ve aynı külfet miktarına sahiptirler.

SQL Server' ın işlem sırası, önce View ve Stored Procedure' lerı sonra Trigger' ları çalıştıracak şekildedir. Daha iyi performans elde etmek için mümkün olduğu kadar trigger seviyesine inilmemeye gayret edilmelidir.

Eğer problemi,Zorlayıcılar seviyesinde yakalayabiliyorsak bu seviyede, stored procedure içinde yakalayabiliyorsak sp seviyesinde o da olmuyorsa, trigger seviyesinde yakalamak gerekir. Sp ile yakalanan bir durum olduğunda, trigger yüzünden, yapılan her şeyin geri alınması gerekmez. Ancak sp’lerin otomatik devreye girmediğini unutulmamalidir.

Cuma, Şubat 02, 2007

SQL SERVER 2000'DE CURSOR (İMLEÇ) KULLANIMI

SQL SERVER 2000'de CURSOR (İmleÇ) KullanImI


Bilgisayar ile uğraşırken sürekli olarak bir yerlere bilgi girmemiz gerekir. Bilgi girişinde en çok muhatap olduğumuz yardımcımız imleç (cursor) tir. Bize bilgisayarın o an hangi alanla ilgilendiğini gösteren ( hatta şu an bile karşımda yanıp sönen ) imleç aynı mantıkla SQL Server üzerinde de tanımlanmıştır.

Cursor'lar (imleçler) SQL Server üzerinden döndürdüğümüz belli bir kayıt kümesi üzerinde satır satır işlem yapabilmemize olanak sağlayan veritabanı nesneleridir.
Satır bazında işlem yapmak aslında programlama ile uğraşanlar için sıradan işlerdendir. Bu tarz bir işlem için genel olarak aşağıdaki adımlar sırayla izlenir;

 Veritabanından veri yığını istemciye çekilir.
 Veri üzerinde, yüksek seviyeli programlama dilleri kullanılarak yazılmış kodlar sayesinde istenilen değişiklikler yapılır. Yüksek seviyeli dillerde sunulan döngü yapıları sayesinde her kaydı tek tek incelemek işten bile değildir.
 Elde edilen sonuç kümesi veritabanına gönderilir.
Bizim üzerinde duracağımız, ikinci yöntem ise aynı işlemleri veritabanı sunucumuz üzerinde yapmaktır.

İki farklı yöntemin de en uygun olduğu durumlar vardır. Örneğin satır bazında T-SQL ile yapamayacağınız karışık işlemleri istemci tarafında yüksek seviyeli bir dil ile yazacağınız kodlar ile kolaylıkla yapabilirsiniz. Ya da T-SQL ile kotarılabilecek satır bazında işlemleri, sunucuda cursor'ları (imleçleri) kullanarak halledebilir ve bu sayede ağ trafiğinin azalmasını sağlayabilirsiniz.

Yüksek seviyeli dillerde sağlanan döngü yapıları yerine sunucuda cursor'ları (imleçleri) kullanırız. Cursor'ların (imleçlerin) kullanım yerlerini örnekler üzerinde inceleyeceğiz. Örnekler için SQL Server 2000 ile gelen 'pubs' örnek veritabanını kullanacağız. İlk örneğimiz 'titles' tablosunda bulunan kitapların fiyatlarını güncellemek olacak.

İş planımıza göre;
 20$ altındaki fiyatlar için artış oranı %10
 20$ ve üzerindeki fiyatlar için artış oranı %5
olduğunu kabul edelim.

Bunun için aşağıdaki standart T-SQL ifadelerini kullanabilir;


UPDATE titles
SET price = price * (price * .1)
WHERE price <>
SET price = price * (price * .05)
WHERE price >= 20

Buradaki sorunu farkettiniz mi? Farkettiğinizi duyar gibiyim. Eğer kitap fiyatı 19.95$ ise ilk ifadede %10'luk artış uygulanacak, bu sayede 20$'ın üstüne çıktığı için ek olarak %5'lik bir artış daha uygulanacak ve istemediğimiz sonuçlar oluşacaktır.

Bu sorunu aşmak için satırları tek tek ele alıp onlar üzerinde işlem yapmak üzere cursor'ları (imleçleri) kullanacağız.

Temel bir cursor (imleç) ifadesi aşağıdaki gibi yazılır.

USE pubs GO DECLARE cr_fiyatlar CURSOR FOR
SELECT price FROM titles
OPEN cr_fiyatlar
FETCH NEXT FROM cr_fiyatlar
WHILE @@FETCH_STATUS = 0 FETCH NEXT
FROM cr_fiyatlar CLOSE cr_fiyatlar
DEALLOCATE cr_fiyatlar

Bu ifadeyi Query Analyzer'da çalıştırdığınızda alttaki şekilde görünene benzer bir sonuç listesi elde edersiniz.






İfadede kullanılan terimlere geçmeden önce, cursor (imleç) kullanmadan sadece SELECT ifadedesi ile aynı verileri elde etmeye çalışsaydık nasıl bir sonuç elde edecektik ona bakalım.
Alttaki Şekilde, cursor (imleçleri) kullanmadan, verileri aynı SELECT ifadesiyle ( SELECT price FROM titles ) seçtiğimizde aldığımız sonucu görüyorsunuz.



Aralarındaki farka dikkat çekmek istiyorum. Cursor (imleç) kullandığınız zaman birer satır içeren sonuç kümeleri döner. Fakat sadece SELECT ifadesi kullandığınızda tüm sonuçlar tek bir küme olarak döner.

Şimdi cursor (imleç) ifademizde kullandığımız terimleri incelersek:

DECLARE cr_fiyatlar CURSOR FOR

Bu ifade yeni bir cursor (imleç) tanımlamak için kullanılır. DECLARE ifadesinden sonra cursor'un (imlecin) adını belirtiriz.

Addan hemen sonra gelen CURSOR FOR ifadesinden sonra ise cursor'un (imlecin) hangi veriler için tanımlayacağımızı belirtiriz.
Örneğimizde ismi 'cr_fiyatlar' olan bir cursor (imleç)

SELECT price FROM titles

' SELECT price FROM titles ' ifadesi ile dönecek olan veri kümesi içinde çalışmak üzere tanımlanıyor. Bu ifade ile dönecek olan veri kümesi üzerinde, tanımladığımız cursor'u (imleci) kullanarak satır satır gezme imkanımız olacak.
Burda titles tablosundan price alani uzerinde satir satir gezmemiz saglanir.

Cursor'un tanımlanacağı veri kümesini tanımlayan SELECT ifadesi içinde, WHERE, GROUP BY ve ORDER BY gibi yardımcı T-SQL komutları da kullanılabilir.

OPEN

OPEN cr_fiyatlar
OPEN deyimi, belirtilen cursor (imleç) için bellekte yer ayırır ve ilk kullanım için gerekli ayarları yapar. Artık cursor (imleç) ilk kullanım için hazırdır.
FETCH
FETCH NEXT FROM cr_fiyatlar
FETCH NEXT deyimi tek bir kaydı alır ve cursor'a (imlece) yükler.
NEXT ifadesi yerine PRIOR (önceki), FIRST (ilki) ve LAST (sonuncusu) gibi ifadeler de kullanabiliriz.

@@FETCH_STATUS
WHILE @@FETCH_STATUS = 0 FETCH NEXT FROM cr_fiyatlar
Örneğimizde cursoru (imleci) WHILE döngüsü ile kontrol etttik. @@FETCH_STATUS ifadesi döngümüzün kontrol birimidir. FETCH ifadesinin sonucuna göre üç farklı değer alabilir.
Bunlar ;
 0: Bir önceki FETCH ifadesi başarılı
 -1: Bir önceki FETCH ifadesi hata ile karşılaştı
 -2: Son kayıt.
Örneğimizde WHILE @@FETCH_STATUS = 0 ifadesi ile hata olmadığı sürece bir sonraki kayıt elde edilir.

Bir cursor'un (imlecin) içine farklı bir cursor (imleç) yerleştirme şansınız da vardır. Alternatif olarak bir cursor (imleç), içinde cursor (imleç) bulunan bir stored procedure (saklı yordam) çağırabilir. Böyle bir durumda @@FETCH_STATUS değerine dikkat etmek gerekir. Çünkü bu fonksiyon döngü düzeyinde değil bağlantı düzeyinde kontrol yapar.
CLOSE

CLOSE cr_fiyatlar

Kayıtlar cursor'a (imlece) yüklendiğinde cursor lock (imleç kilidi) oluşur. Bu kilit, CLOSE ifadesine kadar serbest bırakılmaz. CLOSE ifadesinden sonra cursor (imleç) tekrar açılabilir. Kapatıp açınca cursor (imleç) hiçbir özelliğini kaybetmiş olmaz. Yani bellekten atılmış değildir. CLOSE ile kapatmaktaki amaç kilidi açmaktır.
DEALLOCATE
DEALLOCATE cr_fiyatlar

CLOSE ile cursor'un (imlecin) bellekten temizlenmediğini belirtmiştik. Cursor (imleç) ile işimiz tamamen bittiğinde cursor'u (imleci) kaldırmak için kullanılan bellek alanını boşaltmalı ve değişkenleri yok etmeliyiz. DEALLOCATE bu işlemleri tek seferde yapar. Bu işlemden sonra cursor (bellekten) bellekten kaldırılmıştır.

Cursorlar (imleçler) sayesinde veri kümeleri üzerinde değil, alışık olduğumuz yapısal sorgulamalara benzer şekilde satır satır işlem yapabiliriz. Bu beraberinde bir miktar performans kaybını beraberinde getirir. Ama bazı durumlarda bu, yapılacak karmaşık işlemlerin basitleşmesinden dolayı kabul edilebilir. Buraya kadar bir cursor'un (imlecin) genel olarak nasıl yazıldığını gördük. Şimdi yazımızın başında kurduğumuz senaryoyu gerçekleştirelim.
WHERE CURRENT OF

Yukarıdaki örnekte cursor'un (imlecin) nasıl tanımlandığını görmek için sadece kayıtları listeledik. Fakat çoğu zaman cursor'ları (imleçleri) sadece verileri listemek için kullanmak performansı olumsuz etkileyecektir. Cursor'ları (imleçleri) gerçekten ihtiyacımız olduğunda kullanmaya çalışmalıyız. Örneğimizde güncelle yapmak gerektiğinden, örnek ifademizi güncelleme yapmak üzere aşağıdaki gibi yenilememiz gerekecek.
DECLARE @fiyat MONEY
DECLARE @ cr_fiyatlar CURSOR
SET @ cr_fiyatlar = CURSOR FOR
SELECT price FROM titles
OPEN @ cr_fiyatlar FETCH NEXT FROM @ cr_fiyatlar INTO @fiyat
SELECT price FROM titles WHILE ( @@FETCH_STATUS = 0)
BEGIN
IF @fiyat < price =" (@fiyat">
WHERE CURRENT OF @ cr_fiyatlar ELSE
UPDATE titles SET price = (@fiyat + (@fiyat * .05))
WHERE CURRENT OF @ cr_fiyatlar FETCH NEXT FROM @ cr_fiyatlar INTO @fiyat
END
SELECT price FROM titles
CLOSE @ cr_fiyatlar DEALLOCATE @ cr_fiyatlar
Sekilde görüldüğü gibi yazdığımız T-SQL ifadesi sayesinde istediğimiz sonucu elde ettik. 20$ altındaki fiyatlar %10, 20$ ve üzerindeki fiyatlar %5 arttırılmış durumda.
Bu T-SQL ifadesinde kullandığımız SELECT ifadeleri ;

SELECT price FROM titles

sadece sonucu görmek içindi. Bu ifade olmasaydı güncelleme işlemi yine yapılacak fakat sonuçlar listelenmeyecekti.

Burada asıl dikkat etmemiz gereken WHERE CURRENT OF ifadesi. Bu ifade SQL Server'a o an cursor'un (imlecin) gösterdiği kayıt ile çalışmasını söyler.

Cursor'ların (imleçlerin) performans açısından çok tercih edilmediğini belirtmiştik. Bu yüzden gerekmedikçe cursor (imleç) kullanmamalıyız. Yukardaki örneğimiz için, T-SQL ifademizi biraz genişleterek (örneğin CASE yapısı ya da geçici tablolar kullanarak) cursor (imleç) kullanmadan aynı sonucu elde edebilirdik.

Cursor'lar (imleçler) satır satır hareket etmemize olanak sağlayarak kimi zaman işimizi çok kolaylaştırsalar da çoğu zaman performans kaybına sebep olurlar. Bu yüzden cursor (imleç) kullanmadan yapabileceğimiz işler için, gereksiz yere cursor (imleç) kullanmamaya çalışmalıyız.

Sql transaction





Transaction


Transaction, daha küçük parçalara ayrılamayan işlem demektir. Özellikle bir grup işlemin arka arkaya gerçekleşiyor olmasına rağmen, seri işlemler halinde ele alınması gerektiğinde kullanılır.
Transaction bloğu içerisindeki işlemlerin tamamı gerçekleşinceye kadar hepsi gerçekleşmemiş varsayılır.Bir banka uygulamasını düşünürsek. Bir kullanıcı başka bir kullanıcıya havale yaptığında ne olur. Öncelikle havale yapanın hesap bilgilerinden havale yaptığı miktar düşülür. Ardından alıcının hesabına bu miktar eklenir ve havale gerçekleşmiş olur. Ancak her zaman şartlar istendiği gibi olmayabilir. Örneğin, gönderenin hesabından para düşüldüğü anda elektrik kesilebilir ya da program takılabilir. Bu durumda, ne olur? Örneğin, gönderenin hesabından para düşülmüştür ama alıcının hesabına da geçmemiştir yani bir kısım paranın sahibinin kimliği kaybedilmiş olur. Bu da sistemin olası durumlar dışında veri kaybetmeye müsait bir hal alması demektir. Bu durumun bir şekilde önlenmesi gerekir.

Daha küçük parçalara ayrılamayan en küçük işlem yığınına Transaction denir.

Geçerli kabul edilmesi bir dize işlemlerin tamamının yolunda gitmesine bağlı durumlarda transaction kullanılır.
Transaction bloğu ya hep ya hiç mantığı ile çalışır.
Ya tüm işlemler düzgün olarak gerçekleşir ve geçerli kabul edilir veya bir kısım işlemler yolunda gitse bile, blok sona ermeden bir işlem bile yolunda gitmese hiçbir işlem olmamış kabul edilir. SQL Server 3 farklı transaction desteği sağlar:

1. Harici(Explicit) Transaction: SQL Server'in kullanıcı tarafından bir BEGIN TRAN ifadesi ile transaction'a başlatılması şeklindeki bloktur. Bir aksilik olması halinde SQL Server tarafından veya kullanıcı tarafından COMMIT ifadesi ile gerçekleşmiş olarak veya ROLLBACK ifadesi ile hiç olmamış olarak sonlandırlabilir.

2. Dahili (Implict) Transaction: SQL Server'in belli ifadelerden sonra otomatik olarak transaction açmasını sağlar. Bu modda, bu belli ifadeler kullanıldıktan sonra, kullanıcı tarafından transaction'ın sonlandırılması gerekir. Bu nedenle zahmetli bir mod'dur.

3.Auto Commit: Hiç bir transaction mod'u tayin edilmedi ise, SQL Server bu modda çalışır. Auto Commit modunda iken, her bir batch (yığın, Query Analyzer için iki go arasındaki ifade veya bir defada çalıştırılan bütün SQL ifadeleri) bir transaction bloğu olarak ele alınır. Batch içerisinde bir sorun olursa, SQL Server otomatik olarak bütün batch'i geri alır (ROLLBACK eder).Ancak biz genel olarak transaction denilince, harici transaction işlemlerini kastederiz.

Harici transaction bloğunun başlatılması ve gelişimini ele almak icin aşağıdaki tabloyu kullanirsak:
Hesap tablosu


Genel Yapısı:


1.Transaction bloğu başlatılır. Böylece yapılan işlemlerin geçersiz sayılabileceği VTYS’ye deklare edilmiş olur ve SQL Server Auto Commit modundan çıkıp, Explicit moda geçer.

BEGIN TRAN[SACTION] [transaction_adi]
ile bir transaction başlatılır.

Örnek:






2.Transaction bloğu arasında yapılan her bir işlem bittiği anda başarılı olup olmadığına gerek varsa, programcı tarafından bakılıp, başarılı olmadığı anda geri alım işlemine geçilebilir(ROLLBACK). Ancak bir sorun olması halinde, SQL Server tarafından da verilerin tutarlılığını denetlemek üzere, transaction bloğunun başladığı andan itibaren bir güç kesilmesi gibi durum ortaya çıkarsa, değişiklikler dikkate alınmayacak şekildedir. Bu, transaction logları denilen yöntem ile yapılır. Bu yöntemde, bir transaction başladıktan sonra, verileri tutan sayfalar diskten(HDD) hafızaya(RAM) yüklenir ve ilgili değişiklikler, önce hafızada yapılır. Ardından, değişikliklerin izdüşümü loglar diske yazdırılır, ardından veriler de güncellenir. İşlem başarılı olursa, COMMIT ile transaction bitirilir. Başarısız olduğunun anlaşılması haline ROLLBACK komutu ile transaction başarısız olarak bitirilebilir.(Yani en baştaki duruma geri dönülür)

COMMIT

3. Tüm işlemler tamamlandığı anda COMMIT ile bilgiler yeni hali ile sabitlenir. Başarısız bir sonuç ise ROLLBACK ile en başa alınır ve bilgiler ilk hali ile sabitlenir.


Sabitleme noktaları


Bazen, bir noktaya kadar gelindikten sonra, işlemlerin buraya kadar olanını geçerli kabul etmek isteriz ama, bundan sonraki işlemler için de transaction(geri alabilme seçeneği)ne ihtiyaç duyarız. Bu türden durumlarda sabitleme noktalarından faydalanılır. Bir sabitleme noktası başlatıldığı anda, en başa dönme seçeneği saklı kalmak üzere, noktanın oluşturulduğu yere de dönme seçeneği sunar Genel yapısı şu şekildedir:
SAVE TRANSACTION sabitleme_notkasi_adi

Örnek: