---
title: 'İşlem Denetimi'
source: 'https://academia.sh/tr/kurslar/ileri-sql/islem-denetimi'
course: 'İleri SQL'
language: tr
updated: '2026-08-17T18:08:55+00:00'
license: 'CC BY-SA 4.0'
---

# İşlem Denetimi

Otomatik kesinleştirme kipi, BEGIN ile açık işlem başlatma, COMMIT ve ROLLBACK, deyim hatasının işlemi kendiliğinden bitirmemesi ve bağlantı koptuğunda örtük geri alma.

Önceki konu boyunca yazılan her sorgu tek bir deyimdi ve tek bir soruya yanıt verdi. Veri
değiştiren işler ise çoğu zaman tek deyime sığmaz. Bir kitabın ödünç verilmesi iki değişiklik
gerektirir: ödünç kaydının açılması ve kitabın raf durumunun güncellenmesi. İkisinden biri
yapılıp diğeri yapılmazsa veritabanı, gerçekte var olmayan bir durumu anlatır — kayıt açık
görünürken kitap rafta ya da tersi.

İlişkisel Kuram kursunda ACID özellikleri tanıtılırken atomiklik "ya hep ya hiç" olarak
tanımlanmıştı. **İşlem (transaction)**, bu tanımın uygulamadaki karşılığıdır: birden çok
deyimi, motorun bölünmez saydığı tek bir birim hâline getirir.

## Otomatik Kesinleştirme

Açık bir işlem başlatılmadan çalıştırılan her deyim, kendi başına bir işlemdir. Bu davranışa
**otomatik kesinleştirme (autocommit)** denir: deyim başarıyla biterse etkisi kalıcıdır,
hata verirse hiç olmamış gibidir.

```bash
rm -f k1.db
sqlite3 -box -header k1.db <<'SQL'
CREATE TABLE kitap(id INTEGER PRIMARY KEY, baslik TEXT, rafta INT NOT NULL DEFAULT 1);
INSERT INTO kitap VALUES (1,'Kayip Zaman',1),(2,'Sessiz Ev',1),(3,'Sayilar Kurami',1);
UPDATE kitap SET rafta = 0 WHERE id = 1;
SQL
sqlite3 -box -header k1.db 'SELECT id, baslik, rafta FROM kitap ORDER BY id;'
rm -f k1.db
```

```text
┌────┬────────────────┬───────┐
│ id │     baslik     │ rafta │
├────┼────────────────┼───────┤
│ 1  │ Kayip Zaman    │ 0     │
│ 2  │ Sessiz Ev      │ 1     │
│ 3  │ Sayilar Kurami │ 1     │
└────┴────────────────┴───────┘
```

Birinci komut veritabanını kurup güncelledi ve sona erdi; ikinci komut ayrı bir süreç
olarak açtı ve değişikliği gördü. Hiçbir yerde kesinleştirme yazılmadı, çünkü her deyim
kendiliğinden kesinleşti.

Bu kip tekil değişiklikler için elverişlidir, birlikte olması gereken değişiklikler için
tehlikelidir: iki deyim arasında bir hata olursa birincisi kalıcıdır. Otomatik
kesinleştirmenin açık ya da kapalı olması ve nasıl kapatıldığı motora göre değişir; bazı
motorlarda `BEGIN` yazmak, bazılarında bir ayar değiştirmek gerekir. Değişmeyen, açık
işlemin `COMMIT` ya da `ROLLBACK` ile bitirilmesidir.

## Başlatma, Kesinleştirme, Geri Alma

Açık işlem `BEGIN` ile başlar. O andan sonraki değişiklikler yalnız o işlem içinden
görünür; `COMMIT` çalıştırılana kadar kalıcı değildir. `ROLLBACK`, işlem başladıktan sonra
yapılmış tüm değişiklikleri siler:

```bash
rm -f k2.db
sqlite3 -box -header k2.db <<'SQL'
CREATE TABLE kitap(id INTEGER PRIMARY KEY, baslik TEXT, rafta INT NOT NULL DEFAULT 1);
CREATE TABLE odunc(id INTEGER PRIMARY KEY, kitap_id INT, uye_id INT, alis TEXT, iade TEXT);
INSERT INTO kitap VALUES (1,'Kayip Zaman',1),(2,'Sessiz Ev',1),(3,'Sayilar Kurami',1);

BEGIN;
INSERT INTO odunc(kitap_id, uye_id, alis) VALUES (1, 4, '2024-03-11');
UPDATE kitap SET rafta = 0 WHERE id = 1;
SELECT 'islem icinde' AS an, (SELECT COUNT(*) FROM odunc) AS odunc_sayisi,
       (SELECT rafta FROM kitap WHERE id = 1) AS kitap1_rafta;
ROLLBACK;

SELECT 'geri alindiktan sonra' AS an, (SELECT COUNT(*) FROM odunc) AS odunc_sayisi,
       (SELECT rafta FROM kitap WHERE id = 1) AS kitap1_rafta;
SQL
rm -f k2.db
```

```text
┌──────────────┬──────────────┬──────────────┐
│      an      │ odunc_sayisi │ kitap1_rafta │
├──────────────┼──────────────┼──────────────┤
│ islem icinde │ 1            │ 0            │
└──────────────┴──────────────┴──────────────┘
┌───────────────────────┬──────────────┬──────────────┐
│          an           │ odunc_sayisi │ kitap1_rafta │
├───────────────────────┼──────────────┼──────────────┤
│ geri alindiktan sonra │ 0            │ 1            │
└───────────────────────┴──────────────┴──────────────┘
```

İşlem içinde ödünç kaydı vardı ve kitap raftan düşmüştü. Geri alma sonrasında ikisi de eski
hâline döndü — tek tek değil, **birlikte**. Atomiklik budur: geri alma kısmi bir sonuç
bırakmaz.

İşlem içindeki `SELECT` deyimi, henüz kesinleşmemiş kendi değişikliklerini görüyor. Bu,
işlemin kendi içinde tutarlı olmasının gereğidir; aynı anda başka bir bağlantının bu
satırları görüp göremeyeceği ayrı bir sorudur ve yalıtım düzeyleri dersinde ele alınacaktır.

`COMMIT` yazılsaydı iki değişiklik de kalıcı olurdu. Kesinleştirmenin kalıcılık anlamı da
tanımlıdır: `COMMIT` başarıyla döndüğünde değişiklikler, hemen ardından gelen bir güç
kesintisinde bile kaybolmaz. Motorun bunu nasıl sağladığı — yazma öncesi günlük — İlişkisel
Veritabanı Yönetimi kursunun konusudur.

## Deyim Hatası İşlemi Bitirmez

Sık yapılan bir varsayım, işlem içindeki bir deyimin hata vermesi hâlinde işlemin
kendiliğinden geri alınacağıdır. Standart davranış bu değildir: hata veren **deyim**
etkisiz kalır, işlem açık kalmaya devam eder ve kararı uygulama verir.

Aşağıdaki şemada kısmi bir tekillik dizini var: bir kitabın aynı anda birden çok açık ödünç
kaydı olamaz. İkinci kez ödünç verme denemesi bu kısıta takılır:

```bash
rm -f k3.db
sqlite3 -box -header k3.db <<'SQL'
CREATE TABLE kitap(id INTEGER PRIMARY KEY, baslik TEXT, rafta INT NOT NULL DEFAULT 1);
CREATE TABLE odunc(id INTEGER PRIMARY KEY, kitap_id INT, uye_id INT, alis TEXT, iade TEXT);
CREATE UNIQUE INDEX odunc_acik ON odunc(kitap_id) WHERE iade IS NULL;
INSERT INTO kitap VALUES (1,'Kayip Zaman',0),(2,'Sessiz Ev',1);
INSERT INTO odunc(kitap_id, uye_id, alis) VALUES (1, 4, '2024-03-11');

BEGIN;
INSERT INTO odunc(kitap_id, uye_id, alis) VALUES (1, 7, '2024-03-12');
UPDATE kitap SET rafta = 0 WHERE id = 1;
SELECT 'hata sonrasi islem icinde' AS an, COUNT(*) AS odunc_sayisi FROM odunc;
ROLLBACK;
SELECT 'geri alindiktan sonra' AS an, COUNT(*) AS odunc_sayisi FROM odunc;
SQL
rm -f k3.db
```

```text
Runtime error near line 8: UNIQUE constraint failed: odunc.kitap_id (19)
┌───────────────────────────┬──────────────┐
│            an             │ odunc_sayisi │
├───────────────────────────┼──────────────┤
│ hata sonrasi islem icinde │ 1            │
└───────────────────────────┴──────────────┘
┌───────────────────────┬──────────────┐
│          an           │ odunc_sayisi │
├───────────────────────┼──────────────┤
│ geri alindiktan sonra │ 1            │
└───────────────────────┴──────────────┘
```

Üç şey birden görülüyor. Birincisi, hatalı `INSERT` etkisiz kaldı; ödünç sayısı 1'de
kaldı. İkincisi, işlem **kapanmadı**: sonraki deyimler çalışmayı sürdürdü ve `UPDATE`
uygulandı. Üçüncüsü, geri alma bu `UPDATE` etkisini de sildi.

İkinci nokta, gerçek bir hata kaynağıdır. Hata iletisi göz ardı edilip `COMMIT` yazılsaydı,
ödünç kaydı açılmadığı hâlde kitap raftan düşmüş olarak kesinleşecekti — tam olarak
kaçınılmak istenen tutarsızlık. Bu yüzden uygulama kodunda her deyimin sonucu denetlenir
ve hata durumunda açıkça `ROLLBACK` çalıştırılır.

Hata iletisinin biçimi motora göre değişir; buradaki metin, kısıtın adını ve türünü veren
tipik bir örnektir. Değişmeyen, ihlalin **deyim düzeyinde** raporlanması ve işlemin
kaderinin uygulamaya bırakılmasıdır. Bazı motorlarda işlem, hatadan sonra yalnız geri alma
kabul eden bir kilitli duruma geçer; bu ayrımın hedef motorda bilinmesi gerekir.

## Bağlantı Koptuğunda

Kesinleştirilmemiş bir işlem, bağlantı sona erdiğinde geri alınır. Bu, uygulamanın açık bir
şey yapmasını gerektirmez; motorun garantisidir. Aşağıdaki betik bir işlem başlatıp satır
ekler ve `COMMIT` yazmadan süreci sonlandırır:

```bash
cat > kesintili.mjs <<'JS'
import { DatabaseSync } from 'node:sqlite';

const db = new DatabaseSync('kesinti.db');
db.exec(`
  CREATE TABLE IF NOT EXISTS odunc(id INTEGER PRIMARY KEY, kitap_id INT,
                                   uye_id INT, alis TEXT);
`);
db.exec("BEGIN");
db.exec("INSERT INTO odunc(kitap_id, uye_id, alis) VALUES (1, 4, '2024-03-11')");
console.log('işlem içinde görülen satır:',
            db.prepare('SELECT COUNT(*) AS n FROM odunc').get().n);
process.exit(0);
JS
rm -f kesinti.db
node kesintili.mjs
sqlite3 -box -header kesinti.db 'SELECT COUNT(*) AS yeniden_acildiginda FROM odunc;'
rm -f kesinti.db
```

```text
işlem içinde görülen satır: 1
┌─────────────────────┐
│ yeniden_acildiginda │
├─────────────────────┤
│ 0                   │
└─────────────────────┘
```

Süreç kendi işlemi içinde satırı gördü; veritabanı dosyası yeniden açıldığında satır yoktu.
Tablo tanımı kalıcı oldu, çünkü `CREATE TABLE` işlem başlamadan önce otomatik kesinleştirme
kipinde çalıştı.

Bu davranış, kesinleştirmenin bir eşik olduğunu gösterir: `COMMIT` dönmeden önce hiçbir şey
söz verilmemiştir. Uygulama tarafında bunun karşılığı, işlemi açan kodun her çıkış yolunda
— hata, erken dönüş, kesinti — işlemi kapatmasını güvenceye almaktır.

## İşlemin Sınırını Belirlemek

İşlemin ne kadar geniş tutulacağı bir tasarım kararıdır ve iki yönlü baskı altındadır.

Dar tutulursa birlikte olması gereken değişiklikler ayrı işlemlere düşer ve arada kalan bir
hata tutarsızlık bırakır. İşlemin sınırı, **iş kuralının** sınırıdır: "ödünç verme"
işleminde kayıt açma ile raf durumu güncelleme aynı işlemde olmalıdır.

Geniş tutulursa işlem uzun süre açık kalır; tuttuğu kaynaklar başka bağlantıları bekletir
ve geri alma maliyeti büyür. Kullanıcı girdisi beklerken açık işlem tutmak bu hatanın en
bilinen biçimidir: veritabanı, kullanıcının yanıtını bekleyerek dakikalarca kilit
tutabilir.

Bu iki baskının nasıl dengeleneceği kilitleme davranışı dersinde somutlaşacaktır. Şimdilik
kural olarak: işlem, iş kuralının gerektirdiği en küçük deyim kümesini kapsar ve
başladıktan sonra dış dünyayı beklemez.

## Özet

- Açık işlem başlatılmadan çalıştırılan her deyim kendi başına bir işlemdir; bu kipe
  otomatik kesinleştirme denir.
- `BEGIN` ile açılan işlemde değişiklikler `COMMIT` çalıştırılana kadar kalıcı değildir;
  `ROLLBACK` işlem boyunca yapılmış tüm değişiklikleri birlikte siler.
- Deyim hatası yalnız o deyimi etkisiz kılar; işlem açık kalır ve geri alma kararı
  uygulamaya aittir, hatadan sonra kesinleştirmek kısmi sonucu kalıcı yapar.
- Kesinleştirilmemiş bir işlem, bağlantı sona erdiğinde geri alınır.
- İşlemin sınırı iş kuralının sınırıdır; gereğinden geniş tutulan işlem kaynak tutar ve
  başka bağlantıları bekletir.

## Sonraki Adım

Geri alma bu derste bir "tümünü sil" düğmesiydi: işlemin başına dönmekten başka seçenek
yoktu. Toplu işlerde bu fazla kaba kalır — yüz kitabın envanter kaydı işlenirken üçüncüsü
hatalıysa, ilk ikisini de atmak gereksizdir. Sonraki ders işlem içinde ara duraklar
tanımlamayı, yalnız o duraktan sonrasını geri almayı ve iç içe geri alma noktalarının nasıl
davrandığını gösterecek.
