Hatayı yutma, yeniden fırlat
TRY/CATCH temeli için Hata yönetimi dersine bak. CATCH içinde parametresiz THROW; yakalanan hatayı aynı numarayla çağırana iletir. THROW öncesindeki satır noktalı virgülle bitmelidir.
BEGIN TRY
BEGIN TRY
SELECT 1 / 0;
END TRY
BEGIN CATCH
PRINT N'Kayda yazıldı: ' + ERROR_MESSAGE();
THROW;
END CATCH;
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS dista_yakalanan;
END CATCH;
XACT_STATE
| Değer | Anlam | Yapılabilecek |
|---|---|---|
| 1 | Açık, işlenebilir işlem | COMMIT ya da ROLLBACK |
| 0 | Açık işlem yok | Geri alınacak bir şey yok |
| -1 | Açık ama işlenemez işlem | Okuma ve tam ROLLBACK; yazma ve COMMIT yok |
@@TRANCOUNT işlem var mı der ama işlenebilir mi demez. XACT_STATE ise iç içe sayısını söylemez.
SET XACT_ABORT ON
Çalışma zamanı hatasında işlemi geri alır; TRY içindeyse işlem işlenemez duruma geçer ve CATCH'te XACT_STATE() = -1 görülür. Uygulama zaman aşımında bile kilit bırakmak için yordamların başına konması önerilir.
SET XACT_ABORT ON; BEGIN TRY BEGIN TRANSACTION; DELETE FROM departments WHERE dept_id = 7; SELECT 1 / 0; COMMIT TRANSACTION; END TRY BEGIN CATCH SELECT XACT_STATE() AS durum; IF XACT_STATE() <> 0 ROLLBACK TRANSACTION; END CATCH; SELECT COUNT(*) AS hukuk_duruyor_mu FROM departments WHERE dept_id = 7;
XACT_STATE -1'i yalnız XACT_ABORT ON iken üretir ve o durumda COMMIT ya da yazma Msg 3930 verir. Gerçek sunucuda bazı hatalar XACT_ABORT kapalıyken de işlemi işlenemez yapabilir. Motor ayrıca hatada bütün çalıştırmayı durdurur; gerçek sunucuda birçok hata yalnız o ifadeyi durdurur, XACT_ABORT OFF ise sonraki satır çalışmaya devam eder.Yeniden deneme kalıbı
Deadlock kurbanı 1205 alır ve işlem geri alınmıştır; yeniden denemek güvenlidir. Learn kısa, rastgele bir bekleme öneriyor. Burada 1205 üretemeyiz (tek bağlantı), bu yüzden hatayı THROW ile taklit ediyoruz.
DECLARE @deneme INT = 0, @bitti INT = 0;
WHILE @bitti = 0 AND @deneme < 3
BEGIN
SET @deneme = @deneme + 1;
BEGIN TRY
IF @deneme < 3 THROW 51205, N'Taklit: kurban seçildi', 1;
SET @bitti = 1;
END TRY
BEGIN CATCH
PRINT N'Deneme ' + CAST(@deneme AS NVARCHAR(5)) + N' başarısız';
IF ERROR_NUMBER() <> 51205 THROW;
END CATCH;
END;
SELECT @deneme AS deneme, @bitti AS bitti;