PostgreSQL'de transaction, birden fazla SQL komutunu tek ve bölünmez bir iş olarak çalıştırmanızı sağlar: BEGIN ile başlatırsınız, COMMIT ile tüm değişiklikleri birlikte kalıcı yaparsınız, ROLLBACK ile de hepsini birden iptal edersiniz. Arada bir hata olursa ya da vazgeçerseniz veritabanı, transaction hiç başlamamış gibi eski hâline döner. Siz BEGIN yazmasanız bile PostgreSQL her komutu kendi küçük transaction'ı içinde çalıştırır; buna autocommit davranışı denir.

Bu yazıda transaction bloğunun temel komutlarını, kısmi geri alma için SAVEPOINT kullanımını, hata sonrasında oluşan "aborted" durumunu, psql'in ON_ERROR_ROLLBACK ve AUTOCOMMIT değişkenlerini ve uzun süre açık kalan transaction'lara karşı zaman aşımı ayarlarını çalışan örneklerle anlatıyoruz. Aynı anda çalışan transaction'ların birbirini nasıl gördüğü izolasyon seviyeleri yazısının, bekleme ve kilitlenme konuları da kilitler ve deadlock yazısının konusudur.

Transaction neyi garanti eder?

Transaction neyi garanti eder? Atomiklik, Kalıcılık, Görünürlük

Kılavuzdaki klasik örnek bir banka havalesidir: bir hesaptan para düşülür, diğerine eklenir. Bu iki UPDATE ayrı ayrı çalışırsa ve arada sunucu çökerse, para bir hesaptan çıkmış ama diğerine girmemiş olabilir. Transaction bu riski üç açıdan ortadan kaldırır:

  • Atomiklik: Bloğun içindeki adımların ya hepsi uygulanır ya hiçbiri. Yarım kalmış bir ara durum veritabanına yazılmaz.
  • Kalıcılık: Sunucu COMMIT komutunu onayladığında değişiklikler kalıcı depolamaya kaydedilmiştir; hemen ardından gelen bir çökme bile onları kaybettirmez.
  • Görünürlük: Açık bir transaction'ın yaptığı değişiklikleri diğer oturumlar göremez. Commit anında değişikliklerin tamamı aynı anda görünür hâle gelir.

Bu davranışın altında PostgreSQL'in çok sürümlü eşzamanlılık denetimi (MVCC) yatar. Genel tanıtım için PostgreSQL nedir yazısına, satır sürümlerinin nasıl tutulduğuna ve eşzamanlı okumalara ise izolasyon ve MVCC yazısına bakabilirsiniz.

BEGIN, COMMIT ve ROLLBACK ile ilk örnek

Aşağıdaki örnekte iki hesaplı küçük bir tablo kuruyoruz. CHECK (bakiye >= 0) kısıtı, ileride hata senaryosunu göstermek için işimize yarayacak. İlk blokta havale COMMIT ile kalıcı oluyor, ikinci blokta ise ROLLBACK ile iptal ediliyor:

sql
CREATE TABLE hesap (
    id     int PRIMARY KEY,
    sahip  text NOT NULL,
    bakiye numeric(12,2) NOT NULL CHECK (bakiye >= 0)
);
INSERT INTO hesap VALUES (1, 'Ayşe', 500), (2, 'Mehmet', 100);

BEGIN;
UPDATE hesap SET bakiye = bakiye - 200 WHERE id = 1;
UPDATE hesap SET bakiye = bakiye + 200 WHERE id = 2;
COMMIT;
SELECT * FROM hesap ORDER BY id;
text
 id | sahip  | bakiye
----+--------+--------
  1 | Ayşe   | 300.00
  2 | Mehmet | 300.00
(2 rows)
sql
BEGIN;
UPDATE hesap SET bakiye = bakiye - 50 WHERE id = 1;
SELECT bakiye FROM hesap WHERE id = 1;   -- sonuç: 250.00 (yalnızca bu oturum görür)
ROLLBACK;
SELECT bakiye FROM hesap WHERE id = 1;   -- sonuç: 300.00

İkinci blokta dikkat edilmesi gereken nokta şudur: transaction açıkken yapılan SELECT, kendi değişikliğini (250.00) görür. Aynı anda başka bir oturum bu satırı okusaydı hâlâ 300.00 görürdü. ROLLBACK sonrasında değişiklik hiç yapılmamış gibi ortadan kalkar.

Komutların eş anlamlıları da vardır. Aşağıdaki tablo, kılavuzun başvuru sayfalarındaki karşılıkları özetler:

KomutNe yaparNot
BEGIN [WORK | TRANSACTION]Transaction bloğu başlatırWORK ve TRANSACTION sözcüklerinin etkisi yoktur
START TRANSACTIONBEGIN ile aynı işi yaparSQL standardındaki yazım
COMMIT / ENDDeğişiklikleri kalıcı yaparEND bir PostgreSQL eklentisidir
ROLLBACK / ABORTTüm değişiklikleri iptal ederABORT tarihsel nedenlerle vardır
SAVEPOINT adBlok içinde geri dönülebilecek bir nokta koyarYalnızca blok içinde kullanılabilir
ROLLBACK TO SAVEPOINT adO noktadan sonraki işleri geri alırSavepoint tanımlı kalmaya devam eder
RELEASE SAVEPOINT adSavepoint'i kaldırır, işler korunurAborted durumda kullanılamaz

Autocommit: BEGIN yazmadığınızda ne olur?

PostgreSQL her SQL komutunu bir transaction içinde çalıştırır. Siz BEGIN vermezseniz her komutun etrafına görünmez bir BEGIN ve, komut başarılıysa, bir COMMIT eklenir; başarısızsa o tek komut geri alınır. Bu yüzden tek bir UPDATE bile ya tamamen uygulanır ya hiç uygulanmaz.

Kılavuz burada önemli bir performans notu da düşer: transaction başlatmak ve commit etmek kayda değer CPU ve disk işi gerektirir. Bu nedenle çok sayıda küçük komutu tek bir blok içinde çalıştırmak, her birini ayrı ayrı commit etmekten daha hızlıdır. Toplu yükleme senaryolarında bu konu COPY ile toplu veri aktarımı yazısında ayrıca ele alınıyor.

Hata sonrası "aborted" transaction

Yeni başlayanların en sık takıldığı durum budur. Transaction bloğu içindeki bir komut hata verdiğinde PostgreSQL bloğu iptal edilmiş (aborted) duruma geçirir. Bu noktadan sonra gönderdiğiniz her komut reddedilir; blok ancak ROLLBACK ile (ya da bir savepoint'e dönerek) kapatılabilir. Bakiyeyi eksiye düşürmeye çalışan şu örneğe bakın:

sql
BEGIN;
UPDATE hesap SET bakiye = bakiye - 1000 WHERE id = 1;
SELECT * FROM hesap;
COMMIT;
text
BEGIN
ERROR:  new row for relation "hesap" violates check constraint "hesap_bakiye_check"
DETAIL:  Failing row contains (1, Ayşe, -700.00).
ERROR:  current transaction is aborted, commands ignored until end of transaction block
ROLLBACK

Çıktının son satırına dikkat edin: biz COMMIT yazdık ama sunucu ROLLBACK yanıtı verdi. Aborted durumdaki bir blokta COMMIT aslında geri alma işlemi yapar; hata öncesindeki başarılı komutlar dahil hiçbir değişiklik kalıcı olmaz. Uygulama kodunda "COMMIT çalıştı, demek ki kayıt yazıldı" varsayımı bu yüzden tehlikelidir; commit'in sonucunu ve önceki komutların hata durumunu mutlaka kontrol edin. Hata kodlarının anlamı için sık hatalar ve SQLSTATE kodları yazısına bakabilirsiniz.

SAVEPOINT, ROLLBACK TO ve RELEASE

SAVEPOINT, ROLLBACK TO ve RELEASE: ROLLBACK TO sonrasında savepoint tanımlı kalır; aynı noktaya birden çok kez..., Bir savepoint'e dönmek ya da onu serbest bırakmak, ondan sonra...

Savepoint, transaction içine konan bir işarettir. ROLLBACK TO SAVEPOINT komutu, işaretten sonra yapılan her şeyi geri alır ama işaretten önceki değişiklikleri korur. Kılavuzun da vurguladığı gibi, hata yüzünden aborted duruma düşmüş bir bloğu tamamen geri almadan kurtarmanın tek yolu budur:

sql
BEGIN;
INSERT INTO hesap VALUES (3, 'Zeynep', 50);
SAVEPOINT once;
INSERT INTO hesap VALUES (3, 'Zeynep', 75);   -- aynı id: hata
ROLLBACK TO SAVEPOINT once;
INSERT INTO hesap VALUES (4, 'Can', 75);
RELEASE SAVEPOINT once;
COMMIT;
SELECT * FROM hesap ORDER BY id;
text
BEGIN
INSERT 0 1
SAVEPOINT
ERROR:  duplicate key value violates unique constraint "hesap_pkey"
DETAIL:  Key (id)=(3) already exists.
ROLLBACK
INSERT 0 1
RELEASE
COMMIT
 id | sahip  | bakiye
----+--------+--------
  1 | Ayşe   | 300.00
  2 | Mehmet | 300.00
  3 | Zeynep |  50.00
  4 | Can    |  75.00
(4 rows)

Hata, yalnızca savepoint'ten sonraki komutu geçersiz kıldı; Zeynep'in ilk kaydı ve sonradan eklenen Can kaydı birlikte commit edildi. Savepoint'lerle ilgili kılavuzda geçen birkaç kural günlük kullanımda önemlidir:

  • ROLLBACK TO sonrasında savepoint tanımlı kalır; aynı noktaya birden çok kez dönebilirsiniz.
  • Bir savepoint'e dönmek ya da onu serbest bırakmak, ondan sonra tanımlanmış bütün savepoint'leri de otomatik olarak kaldırır.
  • Aynı adla ikinci bir savepoint tanımlarsanız eskisi silinmez, yalnızca gölgede kalır. Yenisini RELEASE ettiğinizde eski savepoint yeniden erişilebilir olur. SQL standardı burada eskisinin silinmesini ister; PostgreSQL farklı davranır.
  • Aborted durumdaki bir blokta RELEASE SAVEPOINT çalışmaz; önce ROLLBACK TO gerekir.
  • Savepoint'ten sonra alınan kilitler, o savepoint'e geri dönüldüğünde hemen bırakılır.
  • İmleçler (cursor) savepoint'lere karşı tam olarak transaction'a bağlı davranmaz: FETCH ile ilerleyen imlecin konumu geri alınmaz.

PL/pgSQL içindeki BEGIN ... EXCEPTION blokları da arka planda aynı alt transaction mantığıyla çalışır; ayrıntıları PL/pgSQL hata yakalama yazısında bulabilirsiniz.

psql ile transaction: ON_ERROR_ROLLBACK, AUTOCOMMIT ve tek transaction

psql istemcisinin üç özelliği transaction davranışını doğrudan değiştirir. Birincisi ON_ERROR_ROLLBACK değişkenidir. on yapıldığında psql, blok içindeki her komuttan önce sizin yerinize gizli bir savepoint koyar ve komut hata verirse o savepoint'e döner. Böylece hata transaction'ı bozmaz:

sql
\set ON_ERROR_ROLLBACK on
BEGIN;
INSERT INTO hesap VALUES (5, 'Elif', 20);
INSERT INTO hesap VALUES (5, 'Elif', 20);    -- hata, ama blok devam eder
INSERT INTO hesap VALUES (6, 'Burak', 30);
COMMIT;
SELECT id, sahip FROM hesap WHERE id >= 5 ORDER BY id;
text
BEGIN
INSERT 0 1
ERROR:  duplicate key value violates unique constraint "hesap_pkey"
DETAIL:  Key (id)=(5) already exists.
INSERT 0 1
COMMIT
 id | sahip
----+-------
  5 | Elif
  6 | Burak
(2 rows)

Değişken interactive değerini de alır; bu durumda hata yutma yalnızca etkileşimli oturumda yapılır, -f ile okunan betiklerde yapılmaz. Betiklerde bu ayrım güvenlidir, çünkü bir dağıtım betiğinin hatayı görmezden gelip devam etmesi çoğu zaman istenmez.

İkincisi AUTOCOMMIT değişkenidir. Varsayılan on değerinde her komut başarıyla bitince commit edilir. off yapıldığında psql, transaction dışında gönderilen ilk uygun komuttan önce kendisi BEGIN gönderir; siz COMMIT demedikçe hiçbir şey kalıcı olmaz:

sql
\set AUTOCOMMIT off
INSERT INTO hesap VALUES (9, 'Kaan', 10);
ROLLBACK;
SELECT count(*) FROM hesap WHERE id = 9;   -- sonuç: 0

Üçüncüsü komut satırındaki -1 (--single-transaction) seçeneğidir. Bu seçenek, -f veya -c ile verilen her şeyi tek bir BEGIN ... COMMIT içine alır. ON_ERROR_STOP de açıksa hata anında COMMIT yerine ROLLBACK gönderilir ve psql 3 çıkış koduyla biter. Üç satırlık bir betikte ikinci satır hata verdiğinde birinci satırın da geri alındığını görebilirsiniz:

bash
psql -h 127.0.0.1 -U postgres -d ornek_tx -1 -v ON_ERROR_STOP=1 -f yukle.sql
echo $?
text
INSERT 0 1
psql:yukle.sql:2: ERROR:  duplicate key value violates unique constraint "hesap_pkey"
DETAIL:  Key (id)=(1) already exists.
3

Betiğin ilk satırı INSERT 0 1 yanıtı aldı, ama transaction geri alındığı için o kayıt tabloda yok. psql'in diğer seçenekleri için psql komutları rehberine bakabilirsiniz.

Transaction özellikleri: READ ONLY, izolasyon ve AND CHAIN

BEGIN komutu isteğe bağlı olarak transaction kipleri alır: izolasyon seviyesi, READ WRITE ya da READ ONLY erişim kipi ve DEFERRABLE. Aynı ayarlar blok başladıktan sonra SET TRANSACTION ile de verilebilir; ancak izolasyon seviyesi blokta ilk sorgu veya veri değiştiren komut çalıştıktan sonra değiştirilemez:

sql
BEGIN READ ONLY;
DELETE FROM hesap WHERE id = 6;
ROLLBACK;

BEGIN;
SELECT 1;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
ROLLBACK;
text
BEGIN
ERROR:  cannot execute DELETE in a read-only transaction
ROLLBACK
BEGIN
 ?column?
----------
        1
(1 row)

ERROR:  SET TRANSACTION ISOLATION LEVEL must be called before any query
ROLLBACK

Salt okunur kip; geçici olmayan tablolara INSERT, UPDATE, DELETE, MERGE ve COPY FROM, bütün CREATE, ALTER, DROP komutları, GRANT, REVOKE ve TRUNCATE gibi işlemleri engeller. Kılavuz bunun üst düzey bir kavram olduğunu, diske yapılan her yazmayı engellemediğini de not eder. Raporlama oturumlarında yanlışlıkla veri değiştirmeye karşı kullanışlı bir emniyet kemeridir.

COMMIT AND CHAIN ve ROLLBACK AND CHAIN, mevcut transaction'ı bitirip aynı özelliklere sahip yeni bir transaction'ı hemen başlatır. Aşağıda zincirlenen yeni bloğun da repeatable read seviyesinde başladığını görüyoruz:

sql
BEGIN ISOLATION LEVEL REPEATABLE READ;
UPDATE hesap SET bakiye = bakiye + 1 WHERE id = 6;
COMMIT AND CHAIN;
SHOW transaction_isolation;   -- sonuç: repeatable read
COMMIT;

İzolasyon seviyelerinin anlamı ve hangisini ne zaman seçeceğiniz izolasyon seviyeleri yazısında ayrıntılı olarak anlatılıyor.

Transaction içinde neler geri alınır, neler alınmaz?

PostgreSQL'de tablo oluşturma gibi şema değişiklikleri de transaction'a dahildir. Aşağıdaki örnekte oluşturulan tablo, ROLLBACK ile birlikte ortadan kalkıyor; to_regclass boş (NULL) dönüyor:

sql
BEGIN;
CREATE TABLE gecici_rapor (x int);
INSERT INTO gecici_rapor VALUES (1);
ROLLBACK;
SELECT to_regclass('gecici_rapor');   -- sonuç: NULL (boş)

Bu özellik şema geçişlerinde (migration) çok işe yarar: bir dizi ALTER TABLE komutunu tek blokta çalıştırıp, biri başarısız olursa hepsini geri alabilirsiniz. Buna karşılık bazı nesneler transaction kuralına uymaz. Kılavuz özellikle sequence'ları belirtir: nextval ile alınan bir değer, transaction geri alınsa bile geri verilmez ve diğer oturumlara hemen görünür. Identity sütunlarında bu durum numara boşluğu olarak karşınıza çıkar:

sql
CREATE TABLE siparis (id int GENERATED ALWAYS AS IDENTITY, urun text);
BEGIN;
INSERT INTO siparis (urun) VALUES ('kalem');
ROLLBACK;
INSERT INTO siparis (urun) VALUES ('defter');
SELECT * FROM siparis;
text
 id |  urun
----+--------
  2 | defter
(1 row)

Geri alınan "kalem" satırı 1 numarasını tüketti, bu yüzden "defter" 2 aldı. Kesintisiz numara gerektiren fatura gibi alanlar için sequence'a güvenmemek gerekir; ayrıntılar identity, serial ve sequence yazısında. Bazı komutlar ise transaction bloğu içinde hiç çalışmaz. Örneğin VACUUM blok içinde reddedilir, LOCK TABLE ise tam tersine yalnızca blok içinde kullanılabilir:

sql
BEGIN;
VACUUM hesap;
ROLLBACK;
LOCK TABLE hesap IN SHARE MODE;
text
BEGIN
ERROR:  VACUUM cannot run inside a transaction block
ROLLBACK
ERROR:  LOCK TABLE can only be used in transaction blocks

İki aşamalı commit için PREPARE TRANSACTION, COMMIT PREPARED ve ROLLBACK PREPARED komutları da vardır. Hazırlanan bir transaction oturumdan ayrılır ve durumu diske yazılır; daha sonra herhangi bir oturumdan commit veya geri alma yapılabilir. Bu, dağıtık işlem yöneticileri için tasarlanmış ileri bir özelliktir ve unutulan hazırlanmış transaction'lar vacuum işlemini engelleyebilir.

Uzun ve boşta bekleyen transaction'lar

Uzun ve boşta bekleyen transaction'lar: statement_timeout, lock_timeout, idle_in_transaction_session_timeout, transaction_timeout

Açık bir transaction iki şekilde zarar verir. Birincisi aldığı kilitleri sonuna kadar tutar; aynı satırı güncellemek isteyen diğer oturumlar bekler. İkincisi, kılavuzun da belirttiği gibi, açık bir transaction yalnızca kendisinin görebileceği eski satır sürümlerinin temizlenmesini engeller ve tablo şişmesine katkıda bulunur. Bu etkiyi VACUUM ve bloat yazısında gerçek çıktılarla gösteriyoruz.

En tehlikelisi "idle in transaction" durumudur: uygulama BEGIN göndermiş, birkaç komut çalıştırmış ve sonra kullanıcıdan yanıt beklerken bağlantıyı açık bırakmıştır. Buna karşı idle_in_transaction_session_timeout parametresi kullanılır. Aşağıdaki denemede süreyi bir saniyeye indirip blok açıkken iki saniye bekledik. Bekleme için psql'in kabuk komutu çalıştıran \! meta komutuyla Windows'taki ping aracını kullandık; o sırada sunucuya hiçbir sorgu gitmiyor:

sql
SET idle_in_transaction_session_timeout = '1s';
BEGIN;
UPDATE hesap SET bakiye = bakiye WHERE id = 1;
\! ping -n 3 127.0.0.1 > NUL
SELECT 1;
text
SET
BEGIN
UPDATE 1
server closed the connection unexpectedly
	This probably means the server terminated abnormally
	before or while processing the request.
error: connection to server was lost

Sunucu günlüğünde nedeni açıkça yazıyordu: FATAL: terminating connection due to idle-in-transaction timeout. Bağlantı kesildiği için açık transaction geri alındı ve tuttuğu kilitler bırakıldı. Benzer amaçlı diğer parametreler şunlardır:

ParametreNeyi sınırlarAşıldığında
statement_timeoutTek bir komutun süresiniKomut iptal edilir
lock_timeoutBir kilidi bekleme süresiniBekleyen komut iptal edilir
idle_in_transaction_session_timeoutAçık transaction içinde boşta bekleme süresiniOturum sonlandırılır
transaction_timeoutBir transaction'ın toplam süresiniOturum sonlandırılır
idle_session_timeoutTransaction dışında boşta bekleme süresiniOturum sonlandırılır

Hepsinin varsayılanı 0, yani kapalıdır; birim yazmazsanız değer milisaniye kabul edilir. Kılavuz, statement_timeout, lock_timeout ve transaction_timeout değerlerini postgresql.conf içinde genel olarak ayarlamayı önermez, çünkü bütün oturumları etkiler. Bunun yerine SET, ALTER ROLE ... SET veya ALTER DATABASE ... SET ile ilgili kullanıcıya ya da veritabanına özel ayar yapmak daha kontrollüdür. Parametre bağlamları için postgresql.conf ve ALTER SYSTEM yazısına, hangi oturumun ne kadar süredir açık olduğunu bulmak için pg_stat_activity yazısına bakabilirsiniz.

Sık yapılan hatalar

  • Hata sonrası COMMIT'e güvenmek: Aborted bir blokta COMMIT aslında ROLLBACK yapar. Uygulama her komutun sonucunu kontrol etmelidir.
  • Transaction açıkken kullanıcı beklemek: Form doldurulurken açık tutulan bir blok, kilitleri ve eski satır sürümlerini dakikalarca tutar. Kullanıcı etkileşimini transaction dışında yapın.
  • İç içe BEGIN beklemek: Blok içindeyken ikinci BEGIN yalnızca WARNING: there is already a transaction in progress uyarısı verir, yeni bir seviye açmaz. İç içe geri alma için savepoint kullanın.
  • Blok dışında COMMIT ya da ROLLBACK yazmak: Zarar vermez ama WARNING: there is no transaction in progress uyarısı üretir; genellikle bloğun zaten bir hata yüzünden kapandığının işaretidir.
  • Sequence değerinin geri geleceğini sanmak: Geri alınan transaction'lar numara boşluğu bırakır.
  • Çok büyük tek transaction: Milyonlarca satırı tek blokta güncellemek uzun süre kilit tutar ve vacuum'u geciktirir. Mantıklı parçalara bölmeyi düşünün.

PostgreSQL 18 notu

PostgreSQL 18 sürüm notları bu yazıdaki komutların söz dizimini değiştirmiyor. Commit zamanını ilgilendiren bir uyumluluk değişikliği var: AFTER tetikleyicileri artık, olayın kuyruğa alındığı anda etkin olan rolle çalışıyor. Önceden tetikleyici çalıştığı andaki rol (örneğin COMMIT sırasında etkin olan rol) kullanılıyordu. Transaction ortasında SET ROLE ile rol değiştiren uygulamalar bu farkı dikkate almalıdır; tetikleyiciler için trigger oluşturma yazısına bakabilirsiniz. Bu sürümün diğer yenilikleri PostgreSQL 18 yenilikleri yazısında.

Sık Sorulan Sorular

PostgreSQL'de iç içe transaction var mı?

Gerçek anlamda yok. Blok içindeyken verilen ikinci BEGIN yalnızca uyarı üretir. İç içe yapıyı savepoint'lerle kurarsınız: her SAVEPOINT bir alt seviye gibi davranır, ROLLBACK TO ile o seviyeyi geri alır, RELEASE ile üst seviyeye katarsınız.

ROLLBACK ile ABORT arasında fark var mı?

Davranış olarak yok. ABORT tarihsel nedenlerle duran bir eş anlamlıdır; standart SQL yazımı ROLLBACK'tir. Aynı şekilde END de COMMIT ile aynı işi yapan bir PostgreSQL eklentisidir.

Bir hata tüm transaction'ı mı bozar?

Evet; blok içindeki tek bir hata bloğu aborted duruma geçirir ve sonraki komutlar reddedilir. Bloğu kurtarmak için hatadan önce bir savepoint koymuş olmanız gerekir. psql'de ON_ERROR_ROLLBACK bunu sizin yerinize her komut için yapar.

CREATE TABLE ya da ALTER TABLE geri alınabilir mi?

Evet. PostgreSQL'de bu tür şema komutları da transaction'a dahildir ve ROLLBACK ile geri alınır. İstisnalar vardır: VACUUM gibi bazı komutlar blok içinde hiç çalışmaz; komutun başvuru sayfası bu kısıtı ayrıca belirtir.

Hangi zaman aşımı parametresini kullanmalıyım?

Unutulan açık transaction'lar sorun çıkarıyorsa idle_in_transaction_session_timeout, kilit beklemeleri uygulamayı donduruyorsa lock_timeout, kontrolden çıkan uzun sorgular için statement_timeout uygundur. Değerleri iş yükünüze göre seçin ve genel yapılandırma yerine rol veya veritabanı düzeyinde ayarlamayı tercih edin.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: PostgreSQL öğrenme rehberi · İzolasyon seviyeleri ve MVCC · Kilitler ve deadlock · PL/pgSQL hata yakalama · VACUUM ve bloat