Sql & Veritabanı İle Uygulamalar İçin Veri Kayıt İşlem Tetikleyicisi Nasıl Yapılır?

Sql & Veritabanı İle Uygulamalar İçin Veri Kayıt İşlem Tetikleyicisi Nasıl Yapılır?
Sql & Veritabanı İle Uygulamalar İçin Veri Kayıt İşlem Tetikleyicisi Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Tetikleyici (Trigger) mekanizmalarını uygulamak için modern bir ilişkisel veritabanı yönetim sistemine (RDBMS) ihtiyacınız vardır. Bu rehberdeki örnekler PostgreSQL ve MySQL 8.0+ sürümleriyle tam uyumlu olacak şekilde hazırlanmıştır.

  • Veritabanı Sunucusu: PostgreSQL 16+ veya MySQL 8.4 LTS.
  • Yetkilendirme: Veritabanı üzerinde TRIGGER oluşturma yetkisine sahip bir kullanıcı hesabı.
  • Geliştirme Ortamı: DBeaver, pgAdmin veya MySQL Workbench gibi görsel bir veritabanı yönetim aracı.
  • Temel Bilgi: SQL DDL (Veri Tanımlama Dili) ve DML (Veri İşleme Dili) hakkında temel yetkinlik.

Tetikleyici (Trigger) Nedir ve Neden Kullanılır?

Tetikleyici, veritabanındaki belirli bir tablo üzerinde gerçekleşen INSERT, UPDATE veya DELETE işlemleri öncesinde veya sonrasında otomatik olarak çalışan bir veritabanı nesnesidir. Uygulama kodunuzda her seferinde aynı mantığı yazmak yerine, bu mantığı veritabanı seviyesine gömmek, veri tutarlılığını garanti altına alır.

Avantajları:

  • Veri bütünlüğünü merkezi olarak yönetir.
  • Uygulama katmanındaki kod tekrarını azaltır.
  • Denetim (Audit) logları oluşturmak için idealdir.

Adım Adım Veri Kayıt Tetikleyicisi Oluşturma

İlk adımda, bir tabloya yeni kayıt eklendiğinde bu kaydın ne zaman ve kim tarafından oluşturulduğunu otomatik olarak kaydeden bir yapı kuralım. Öncelikle bir "log" tablosuna ihtiyacımız var.

CREATE TABLE kullanici_log (
    log_id SERIAL PRIMARY KEY,
    islem_turu VARCHAR(10),
    tablo_adi VARCHAR(50),
    kayit_zamani TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Yukarıdaki kod, işlemlerin kaydedileceği merkezi bir tablo oluşturur. Şimdi, ana tablomuzdaki her yeni kayıtta bu tabloya veri girişi yapacak tetikleyiciyi hazırlayalım.

Fonksiyonel Tetikleyici Yazımı ve Mantığı

PostgreSQL gibi sistemlerde tetikleyiciler genellikle bir "fonksiyon" (function) ile tetiklenir. Bu, tetikleyicinin işleyeceği mantığı bir modül haline getirir.

CREATE OR REPLACE FUNCTION log_kayit_ekle()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO kullanici_log (islem_turu, tablo_adi)
    VALUES (TG_OP, TG_TABLE_NAME);
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Bu fonksiyon, TG_OP (operasyon türü) ve TG_TABLE_NAME (tablo adı) gibi yerleşik değişkenleri kullanarak dinamik bir kayıt oluşturur. RETURN NEW ifadesi, tetiklenen işlemin devam etmesini sağlar.

Tetikleyiciyi Tabloya Bağlama (Trigger Tanımlama)

Fonksiyonu oluşturduktan sonra, bu fonksiyonun hangi tabloda ve hangi olaydan sonra çalışacağını belirtmemiz gerekir. Bu aşama tetikleyicinin "aktif" hale geldiği yerdir.

CREATE TRIGGER trg_kullanici_eklendikten_sonra
AFTER INSERT ON kullanicilar
FOR EACH ROW
EXECUTE FUNCTION log_kayit_ekle();

Burada AFTER INSERT ifadesi, işlemin veritabanına başarıyla yazılmasından hemen sonra tetikleyicinin devreye gireceğini belirtir. FOR EACH ROW ise her bir satır için ayrı ayrı çalışmasını sağlar.

Tetikleyici Performansı ve En İyi Pratikler

Tetikleyiciler güçlü araçlardır ancak yanlış kullanıldığında veritabanı performansını ciddi şekilde düşürebilirler. Özellikle çok yoğun trafik alan sistemlerde "recursive" (iç içe) tetikleyicilerden kaçınmalısınız.

Yöntem Avantajı Dezavantajı
AFTER Trigger Veri tutarlılığını garanti eder. İşlem süresini uzatabilir.
BEFORE Trigger Veriyi kaydetmeden değiştirebilir. Hata yönetimi daha karmaşıktır.
Kritik Güvenlik Uyarısı: Tetikleyiciler içerisinde karmaşık dış servis çağrıları yapmaktan kaçının. Veritabanı tetikleyicileri, sadece veritabanı içindeki tutarlılıkla ilgilenmelidir. Dış API çağrıları veya dosya sistemi işlemleri için uygulama katmanını (Backend) kullanın.

Sıkça Sorulan Sorular

Tetikleyiciler veritabanını yavaşlatır mı?

Evet, gereğinden fazla karmaşık veya ağır sorgular içeren tetikleyiciler, her kayıt işleminde çalışacağı için yazma (write) operasyonlarını yavaşlatabilir. Tetikleyici mantığını mümkün olduğunca hafif tutmalısınız.

Tetikleyiciyi nasıl devre dışı bırakabilirim?

PostgreSQL'de ALTER TABLE tablo_adi DISABLE TRIGGER trg_adi; komutu ile tetikleyiciyi geçici olarak durdurabilirsiniz.

Tetikleyiciler hata ayıklama (debug) için uygun mudur?

Tetikleyiciler hata ayıklama için zorlayıcı olabilir. Hata durumunda RAISE EXCEPTION kullanarak işlemi tamamen iptal edebilir ve uygulama tarafında hata mesajı alabilirsiniz.

Aynı tabloda birden fazla tetikleyici olabilir mi?

Evet, aynı olay (örneğin INSERT) için birden fazla tetikleyici tanımlayabilirsiniz. Ancak bu tetikleyicilerin çalışma sırasını yönetmek karmaşıklaşabilir.

Tetikleyici ile veriyi doğrulayabilir miyim?

Evet, BEFORE INSERT tetikleyicisi kullanarak verinin formatını kontrol edebilir ve hata durumunda işlemi engelleyebilirsiniz.

Tetikleyicilerde Hata Yönetimi ve Exception Handling

Tetikleyiciler, veritabanı işlemlerinin tam kalbinde yer aldıkları için, tetikleyici içerisinde oluşabilecek bir hata tüm işlemi (transaction) durdurabilir. Bu durum, veri bütünlüğünü korumak için istenen bir davranış olsa da, uygulamanın beklenmedik şekilde çökmesine neden olabilir. Profesyonel bir yaklaşım, tetikleyici içerisinde EXCEPTION bloklarını kullanarak hataları kontrollü bir şekilde yönetmektir.

Örneğin, bir kayıt ekleme sırasında tetikleyicinin hata fırlatması yerine, hatayı log tablosuna yazıp işlemi devam ettirmek veya özel bir hata mesajı dönmek daha güvenli olabilir.

CREATE OR REPLACE FUNCTION log_error_trigger()
RETURNS TRIGGER AS $$
BEGIN
    -- İşlem mantığı
    IF NEW.price < 0 THEN
        RAISE EXCEPTION 'Fiyat negatif olamaz: %', NEW.price;
    END IF;
    RETURN NEW;
EXCEPTION WHEN OTHERS THEN
    -- Hata loglama tablosuna kayıt at
    INSERT INTO error_logs(error_message, created_at) 
    VALUES (SQLERRM, NOW());
    RETURN NULL; -- İşlemi iptal et
END;
$$ LANGUAGE plpgsql;

Tetikleyici Test Senaryoları (Unit Testing)

Tetikleyicilerin karmaşıklığı arttıkça, sadece manuel SQL sorguları ile test yapmak yetersiz kalır. Tetikleyicilerinizi test ederken şu üç senaryoyu mutlaka göz önünde bulundurmalısınız:

  • Normal Senaryo: Verinin beklendiği gibi işlenip log tablosuna yazıldığını doğrulamak.
  • Sınır Değerler (Edge Cases): NULL değerler, boş stringler veya maksimum limit değerleri ile tetikleyicinin nasıl tepki verdiğini ölçmek.
  • Toplu İşlemler (Bulk Operations): INSERT INTO ... SELECT gibi tek seferde binlerce satır eklenen işlemlerde tetikleyicinin performansını ve hata yönetimini test etmek.

Aşağıdaki örnek, bir tetikleyicinin toplu işlemlerde nasıl davranacağını test etmek için kullanılan basit bir SQL blok yapısını göstermektedir:

-- Test verisi oluşturma
DO $$
BEGIN
    FOR i IN 1..100 LOOP
        INSERT INTO products (name, price) VALUES ('Test Ürün ' || i, i * 10);
    END LOOP;
END $$;

-- Tetikleyicinin çalışıp çalışmadığını kontrol et
SELECT COUNT(*) FROM audit_log_table;

Tetikleyici Deployment Stratejileri

Canlı (production) ortamlarda tetikleyici güncellemek, veritabanı kilitlenmelerine (locking) yol açabilir. Bu nedenle şu stratejileri izlemek kritiktir:

  1. Migration Araçları Kullanımı: Liquibase veya Flyway gibi araçlar kullanarak tetikleyici değişikliklerini versiyon kontrol sistemine dahil edin.
  2. Düşük Trafik Saatleri: Büyük tablolarda tetikleyici eklemek veya değiştirmek, tablonun kilitlenmesine neden olabilir. Bu işlemleri sistemin en az kullanıldığı saatlerde gerçekleştirin.
  3. Önce Test, Sonra Canlı: Tetikleyiciyi önce bir staging (test) veritabanında, ardından canlı ortamda uygulayın.
İpucu: Eğer çok yoğun bir veritabanı üzerinde çalışıyorsanız, tetikleyici yerine "Event-Driven" mimariyi tercih ederek, işlemleri veritabanı dışına (Queue/Message Broker) taşıyabilirsiniz. Bu, veritabanı üzerindeki yükü ciddi oranda azaltır.

Sonuç

Sql & veritabanı ile uygulamalar için veri kayıt işlem tetikleyicisi oluşturmak, sisteminizin veri güvenliğini ve tutarlılığını bir üst seviyeye taşır. Bu rehberde öğrendiğiniz fonksiyon tabanlı tetikleyiciler ve loglama mekanizması, profesyonel projelerde en sık kullanılan yöntemlerden biridir.

Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) uygulamadan önce mutlaka yedekleme yapın ve tetikleyicilerin sistem yükü üzerindeki etkisini test edin. Güvenlik için veritabanı kullanıcı yetkilerini en düşük seviyede tutun.

Bir sonraki adım olarak, tetikleyicilerle oluşturduğunuz log tablolarını otomatik olarak temizleyen pg_cron gibi zamanlanmış görevleri (scheduled tasks) inceleyerek veritabanı bakım süreçlerinizi otomatize edebilirsiniz.

Bu yazıya tepkinizi paylaşın:
Deniz Aydın

On yıldır pratik yaşam çözümleri üzerine içerik üretiyorum. Okuyucuların karmaşık sorunlarını en basit yöntemlerle çözmelerine yardımcı olmayı hedefliyorum.

Yorumlar (0)

Yorum Yaz