Thursday, March 26, 2026

XACT_ABORT

SELECT CASE 
    WHEN ( ( ( @@OPTIONS & 512 ) = 512 ) ) THEN 'ON' 
    ELSE 'OFF' 
END AS XACT_ABORT_STATUS;

-- When XACT_ABORT is ON → any runtime error rolls back the entire transaction automatically.
-- When OFF → some errors (like PK violations) do not abort the transaction, and subsequent statements still run.

SET XACT_ABORT ON;

CREATE TABLE MyTable (
    Id INT PRIMARY KEY,
    Name VARCHAR(100)
);


SELECT * FROM MyTable;

BEGIN TRANSACTION;
INSERT INTO MyTable (Id, Name) VALUES (1, 'Alice');
INSERT INTO MyTable (Id, Name) VALUES (1, 'Bob');
-- INSERT INTO MyTable (Id, Name)
-- SELECT 1, 'Bob'
-- WHERE NOT EXISTS (
--     SELECT 1
--     FROM MyTable
--     WHERE Id = 1
-- );
SELECT * FROM MyTable;
commit;

SELECT * FROM MyTable;

Output is

Output:

303 ms
XACT_ABORT_STATUS
-----------------
ON               
Id          Name                                                                                                
----------- ----------------------------------------------------------------------------------------------------
Msg 2627, Level 14, State 1, Server 6f1d64a248a3, Line 23
Violation of PRIMARY KEY constraint 'PK__MyTable__3214EC07149F63D5'. Cannot insert duplicate key in object 'dbo.MyTable'. The duplicate key value is (1).

Eğer OFF yaparsak
Output:

433 ms
XACT_ABORT_STATUS
-----------------
ON               
Id          Name                                                                                                
----------- ----------------------------------------------------------------------------------------------------
Msg 2627, Level 14, State 1, Server de2db788b1d3, Line 23
Violation of PRIMARY KEY constraint 'PK__MyTable__3214EC078BA094A9'. Cannot insert duplicate key in object 'dbo.MyTable'. The duplicate key value is (1).
The statement has been terminated.
Id          Name                                                                                                
----------- ----------------------------------------------------------------------------------------------------
          1 Alice                                                                                               
Id          Name                                                                                                
----------- ----------------------------------------------------------------------------------------------------
          1 Alice   


Wednesday, March 25, 2026

DuplicateKeyException

Giriş

Elimizde legacy bir veri tabanı var. Primary Key (PK) alanların datetime + ms şeklinde tasarlanmış. Böylece satırların kolayca sıralanabileceği düşünülmüş. Ancak bir problem var. Yazma istekleri arttıkça DuplicateKeyException hataları alıyoruz. Yani aslında veri tabanı saati PK için iyi bir kaynak değil. Çünkü aynı anda gelen iki istek için aynı zaman değerini verebiliyor


Ancak PK olarak şu seçenekleri değerlendirebiliriz

  • - Sequence kullanılsaydı harika olurdu
  • - Snowflake Id kullanılsaydı yine olurdu  ancak o zamanlar Snowflake yoktu
  • - UUIDv4 kullanamıyoruz, çünkü sırayı kaybediyoruz
  • - UUIDv7 kullanılabilir, sırayı muhafaza ederiz
  • - PK'ya bir alan daha ilave edebilsek, rastgele bir şey örneğin threadId problemi azaltır, tam çözmez


Wednesday, March 11, 2026

Table Partitioning

Giriş
Data Loding yaparken kullanılabilecek yöntemler şöyle
1. bcp
2. BULK INSERT
3. SQL Server Integration Services (SSIS)

Açıklaması şöyle
Table partitioning is one of the most powerful strategies for improving load performance while maintaining data availability. At a financial services company processing billions of monthly transactions, implementing partition switching transformed their loading process. Instead of inserting directly into the main table and blocking queries, we loaded an identical staging table and instantly switched it into the partitioned main table: 
Örnek
Şöyle yaparız
-- Create staging table with same structure as target partition
SELECT * INTO Sales.Transactions_Staging
FROM Sales.Transactions
WHERE 1 = 0;

-- Load staging table (much faster than loading production table)
BULK INSERT Sales.Transactions_Staging
FROM '\\FileServer\Imports\NewTransactions.csv'
WITH (FIELDTERMINATOR = ',', ROWTERMINATOR = '\n');

-- Switch staging table into partition in an instant operation
ALTER TABLE Sales.Transactions
SWITCH PARTITION 12 TO Sales.Transactions_Staging;

XACT_ABORT

SELECT CASE      WHEN ( ( ( @@OPTIONS & 512 ) = 512 ) ) THEN 'ON'      ELSE 'OFF'  END AS XACT_ABORT_STATUS; -- When XAC...