ডেটাবেজ Transaction কী?

Transaction হলো ডেটাবেজে একটি বা একাধিক SQL অপারেশনের একটি একক একক (unit) যা একসাথে সম্পন্ন হয়। হয় সবগুলো অপারেশন সফলভাবে সম্পন্ন হবে, না হলে কোনোটাই হবে না।

বাস্তব উদাহরণ: ব্যাংক Transfer — Account A থেকে টাকা কাটলে অবশ্যই Account B-তে টাকা যোগ হতে হবে। মাঝপথে কোনো সমস্যা হলে পুরো Transaction রদ হয়ে যাবে।


Transaction-এর ACID বৈশিষ্ট্য

বৈশিষ্ট্য বিবরণ
Atomicity সব অপারেশন একসাথে সফল বা ব্যর্থ
Consistency ডেটা সবসময় valid অবস্থায় থাকবে
Isolation একাধিক Transaction পরস্পর থেকে বিচ্ছিন্ন
Durability Commit হলে ডেটা স্থায়ীভাবে সংরক্ষিত

SQL Transaction

-- Transaction শুরু
BEGIN TRANSACTION; -- বা START TRANSACTION;

-- Bank Transfer
UPDATE accounts SET balance = balance - 5000 WHERE id = 1;  -- A থেকে কাটা
UPDATE accounts SET balance = balance + 5000 WHERE id = 2;  -- B-তে যোগ

-- সফল হলে
COMMIT;

-- সমস্যা হলে
ROLLBACK;

Spring Boot-এ Transaction

@Transactional Annotation

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class BankService {

    @Autowired
    private AccountRepository accountRepository;

    // পুরো মেথড একটি Transaction-এ চলবে
    @Transactional
    public void transferMoney(Long fromId, Long toId, double amount) {
        Account from = accountRepository.findById(fromId)
            .orElseThrow(() -> new RuntimeException("Account not found"));
        Account to = accountRepository.findById(toId)
            .orElseThrow(() -> new RuntimeException("Account not found"));

        if (from.getBalance() < amount) {
            throw new RuntimeException("Insufficient balance!");
        }

        from.setBalance(from.getBalance() - amount);
        to.setBalance(to.getBalance() + amount);

        accountRepository.save(from);
        accountRepository.save(to);
        // Exception হলে স্বয়ংক্রিয়ভাবে ROLLBACK হবে
    }
}

Transaction Propagation

Transaction Propagation নির্ধারণ করে — নতুন মেথড কলে নতুন Transaction তৈরি হবে নাকি বিদ্যমান Transaction-এ যোগ হবে।

@Service
public class OrderService {

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private InventoryService inventoryService;

    // REQUIRED (ডিফল্ট): বিদ্যমান Transaction ব্যবহার করে, না থাকলে নতুন তৈরি করে
    @Transactional(propagation = Propagation.REQUIRED)
    public void placeOrder(Order order) {
        orderRepository.save(order);
        paymentService.processPayment(order);  // একই Transaction-এ
        inventoryService.reduceStock(order);    // একই Transaction-এ
    }

    // REQUIRES_NEW: সবসময় নতুন Transaction তৈরি করে
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void logAudit(String message) {
        // এই Transaction আলাদা — Parent রোলব্যাক হলেও এটি সংরক্ষিত থাকে
        auditRepository.save(new AuditLog(message));
    }

    // NESTED: Parent Transaction-এর ভেতরে Nested Transaction
    @Transactional(propagation = Propagation.NESTED)
    public void processPayment(Order order) {
        // Savepoint তৈরি হয় — এই অংশ fail হলে শুধু এটুকু rollback হয়
        paymentRepository.save(new Payment(order));
    }

    // NOT_SUPPORTED: Transaction ছাড়াই চলে
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<Product> getProductList() {
        return productRepository.findAll();
    }
}

Transaction Isolation Level

@Service
public class ReportService {

    // READ_COMMITTED: Dirty Read প্রতিরোধ করে (সবচেয়ে সাধারণ)
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public List<Order> getOrders() {
        return orderRepository.findAll();
    }

    // SERIALIZABLE: সর্বোচ্চ Isolation, Phantom Read প্রতিরোধ
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public double calculateBalance(Long accountId) {
        return accountRepository.findById(accountId)
            .map(Account::getBalance)
            .orElse(0.0);
    }
}

Rollback নিয়ম

@Service
public class ProductService {

    // ডিফল্ট: RuntimeException এবং Error-এ Rollback হয়
    @Transactional
    public void updateProduct(Product product) {
        productRepository.save(product);
        // RuntimeException হলে Rollback হবে
    }

    // Checked Exception-এও Rollback করতে চাইলে
    @Transactional(rollbackFor = Exception.class)
    public void importProducts(List<Product> products) throws IOException {
        for (Product p : products) {
            productRepository.save(p);
        }
        // IOException হলেও Rollback হবে
    }

    // নির্দিষ্ট Exception-এ Rollback করবে না
    @Transactional(noRollbackFor = NotFoundException.class)
    public void processOrders(List<Long> ids) {
        for (Long id : ids) {
            try {
                processOrder(id);
            } catch (NotFoundException e) {
                // NotFoundException এ Rollback হবে না, অন্যগুলো চলতে থাকবে
                log.warn("Order not found: " + id);
            }
        }
    }
}

Read-Only Transaction

@Service
public class DashboardService {

    // Read-Only Transaction — Performance উন্নত হয়
    @Transactional(readOnly = true)
    public DashboardData getDashboardData() {
        long userCount = userRepository.count();
        long orderCount = orderRepository.count();
        double revenue = orderRepository.getTotalRevenue();
        return new DashboardData(userCount, orderCount, revenue);
    }
}

Transaction Timeout

@Service
public class ReportService {

    // ৩০ সেকেন্ডের মধ্যে শেষ না হলে Transaction বাতিল
    @Transactional(timeout = 30)
    public byte[] generateLargeReport() {
        // বড় রিপোর্ট তৈরির কাজ
        return reportGenerator.generate();
    }
}

সংক্ষেপে

বিষয় বিবরণ
@Transactional মেথডকে Transaction-এ মোড়ে
REQUIRED বিদ্যমান Transaction ব্যবহার করে (ডিফল্ট)
REQUIRES_NEW সবসময় নতুন Transaction
rollbackFor কোন Exception-এ Rollback হবে
readOnly = true Read-only transaction (দ্রুত)
timeout Transaction-এর সর্বোচ্চ সময়

উপসংহার

Database Transaction ডেটার সামঞ্জস্য (Consistency) ও নির্ভরযোগ্যতা নিশ্চিত করে। Spring Boot-এ @Transactional Annotation ব্যবহার করে সহজেই Transaction Management করা যায়। Propagation, Isolation Level এবং Rollback নিয়ম সঠিকভাবে বুঝলে একটি robust ও নির্ভরযোগ্য অ্যাপ্লিকেশন তৈরি করা সম্ভব।

Share