SQL Notları: Transactions

MySQL’de işlemler (transactions), bir grup SQL ifadesini tek bir iş birimi olarak yönetmeyi sağlar. Bu, özellikle veri tutarlılığı ve bütünlüğü gerektiren durumlarda önemlidir. Bu yazıda, MySQL’de işlemlerin nasıl başlatılacağını, `COMMIT` ve `ROLLBACK` komutlarının nasıl kullanılacağını ve JDBC sürücüsü ile işlemlerin nasıl yönetileceğini ele alacağız.

#### 1. İşlem Başlatma (START TRANSACTION)

Bir işlem, bir grup SQL ifadesini (SELECT, INSERT, UPDATE, DELETE) tek bir iş birimi olarak yönetir. İşlem içindeki her bir işlem başarılı olmalıdır, aksi takdirde tüm işlem geri alınır (ROLLBACK).

##### Örnek: İşlem Başlatma ve COMMIT

Aşağıdaki örnekte, iki hesap arasında para transferi yapılan bir işlem gösterilmiştir:

“`sql
START TRANSACTION;

SET @transAmt = 500;
SELECT @availableAmt := ledgerAmt FROM accTable WHERE customerId = 1 FOR UPDATE;

IF @availableAmt >= @transAmt THEN
   UPDATE accTable SET ledgerAmt = ledgerAmt – @transAmt WHERE customerId = 1;
   UPDATE accTable SET ledgerAmt = ledgerAmt + @transAmt WHERE customerId = 2;
   COMMIT;
ELSE
   ROLLBACK;
END IF;
“`

**ACID Özellikleri:**

– **Atomicity (Atomiklik):** İşlem içindeki tüm işlemler ya tamamen başarılı olur ya da hiçbiri uygulanmaz.
– **Consistency (Tutarlılık):** İşlem başarılı bir şekilde tamamlandığında, veritabanı tutarlı bir durumda olur.
– **Isolation (İzolasyon):** İşlemler birbirinden bağımsız çalışır.
– **Durability (Dayanıklılık):** İşlem tamamlandığında, sonuçlar kalıcı olarak kaydedilir.

#### 2. COMMIT, ROLLBACK ve AUTOCOMMIT

##### AUTOCOMMIT

MySQL, varsayılan olarak `AUTOCOMMIT` modunu etkinleştirir. Bu, her SQL ifadesinin otomatik olarak commit edilmesi anlamına gelir. `AUTOCOMMIT` modunu devre dışı bırakmak için:

“`sql
SET AUTOCOMMIT = 0;  — AUTOCOMMIT’i devre dışı bırak
SET AUTOCOMMIT = 1;  — AUTOCOMMIT’i etkinleştir
“`

`AUTOCOMMIT` durumunu kontrol etmek için:

“`sql
SELECT @@autocommit;
“`

##### COMMIT

`AUTOCOMMIT` devre dışı bırakıldığında, yapılan değişiklikler sadece mevcut bağlantı için görünür olur. `COMMIT` komutu ile değişiklikler kalıcı hale getirilir ve tüm bağlantılar için görünür olur.

##### ROLLBACK

Bir hata oluştuğunda veya işlem başarısız olduğunda, `ROLLBACK` komutu ile yapılan tüm değişiklikler geri alınır.

##### Örnek: COMMIT ve ROLLBACK

“`sql
— AUTOCOMMIT’i devre dışı bırak
SET AUTOCOMMIT = 0;

— Yeni bir satır ekle
INSERT INTO testTable VALUES (2), (3);

— Değişiklikleri commit et
COMMIT;

— ROLLBACK çalıştır (COMMIT’ten sonra ROLLBACK etkisizdir)
ROLLBACK;
“`

#### 3. JDBC Sürücüsü ile İşlem Yönetimi

JDBC sürücüsü kullanarak MySQL’de işlem yönetimi yapılabilir. İşlemler, `Connection` nesnesi üzerinden yönetilir.

##### Örnek: JDBC ile İşlem Yönetimi

“`java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class accTrans {

   public static void doTransfer(double transAmount, int customerIdFrom, int customerIdTo) {
       Connection con = null;
       PreparedStatement pstmt = null;
       ResultSet rs = null;

       try {
           String DB_CONNECTION_URL = “jdbc:mysql://localhost:3306/testDB?useUnicode=true&characterEncoding=utf8”;
           Class.forName(“com.mysql.jdbc.Driver”);
           con = DriverManager.getConnection(DB_CONNECTION_URL, “user”, “password”);

           // AUTOCOMMIT’i devre dışı bırak
           con.setAutoCommit(false);

           // Miktar kontrolü
           double availableAmt = 0;
           pstmt = con.prepareStatement(“SELECT ledgerAmt FROM accTable WHERE customerId = ? FOR UPDATE”);
           pstmt.setInt(1, customerIdFrom);
           rs = pstmt.executeQuery();
           if (rs.next()) {
               availableAmt = rs.getDouble(1);
           }

           if (availableAmt >= transAmount) {
               // Miktarı çek
               pstmt = con.prepareStatement(“UPDATE accTable SET ledgerAmt = ledgerAmt – ? WHERE customerId = ?”);
               pstmt.setDouble(1, transAmount);
               pstmt.setInt(2, customerIdFrom);
               pstmt.executeUpdate();

               // Miktarı yatır
               pstmt = con.prepareStatement(“UPDATE accTable SET ledgerAmt = ledgerAmt + ? WHERE customerId = ?”);
               pstmt.setDouble(1, transAmount);
               pstmt.setInt(2, customerIdTo);
               pstmt.executeUpdate();

               // İşlemi commit et
               con.commit();
           } else {
               // Yetersiz bakiye durumunda rollback
               con.rollback();
           }
       } catch (SQLException ex) {
           // Hata durumunda rollback
           try {
               if (con != null) con.rollback();
           } catch (SQLException e) {
               e.printStackTrace();
           }
       } finally {
           // Kaynakları serbest bırak
           try {
               if (rs != null) rs.close();
               if (pstmt != null) pstmt.close();
               if (con != null) con.close();
           } catch (SQLException ex) {
               ex.printStackTrace();
           }
       }
   }

   public static void main(String[] args) {
       doTransfer(500, 1020, 1021);
   }
}
“`

#### Sonuç

MySQL’de işlemler, veri tutarlılığı ve bütünlüğü sağlamak için kritik öneme sahiptir. `START TRANSACTION`, `COMMIT` ve `ROLLBACK` komutları ile işlemler yönetilebilir. JDBC sürücüsü kullanarak da Java uygulamalarında işlem yönetimi yapılabilir. Bu yöntemler, veritabanı işlemlerini daha güvenli ve tutarlı hale getirir. Bir sonraki yazıda görüşmek üzere!