0% found this document useful (0 votes)
4 views16 pages

Transaction

The document outlines the seven transaction propagation levels in Spring, detailing their behaviors, use cases, and rollback impacts. It also explains the various isolation levels available in Spring Boot, their definitions, and how they help prevent issues like dirty reads, non-repeatable reads, and phantom reads. Additionally, it provides guidance on recommended isolation levels based on specific use cases to ensure data integrity and performance.

Uploaded by

badityaa1977
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views16 pages

Transaction

The document outlines the seven transaction propagation levels in Spring, detailing their behaviors, use cases, and rollback impacts. It also explains the various isolation levels available in Spring Boot, their definitions, and how they help prevent issues like dirty reads, non-repeatable reads, and phantom reads. Additionally, it provides guidance on recommended isolation levels based on specific use cases to ensure data integrity and performance.

Uploaded by

badityaa1977
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

AMIT IT

Contact Details:
📞 Phone: 7507502027
🌐 Website: [Link]
🏢 Office Address: A-8, UG Floor, Pentagon Tower, Karve Nagar, Pune

Spring Transactions
Spring Transaction Propagation Levels (Detailed Notes)

Spring provides 7 different transaction propagation levels to control how transactions


behave in different scenarios. The propagation attribute in @Transactional defines how the
transaction should be managed.

1. [Link] (Default)
✅ Behavior:
If a transaction already exists, it joins the existing transaction.
If no transaction exists, it creates a new one.

✅ Use Case:
Suitable for most service methods that need to be executed in a single transactional
context.

✅ Example:
@Transactional(propagation = [Link])

public void methodA() {

// Uses existing transaction if available

✅ Scenario:
Caller Transaction Called Method Transaction Final Behavior
(REQUIRED)

Exists Joins existing transaction Single transaction

Does not exist New transaction created New transaction

✅ Rollback Impact:
If methodA throws an exception, everything rolls back.

2. Propagation.REQUIRES_NEW
✅ Behavior:
Always creates a new transaction.
If an existing transaction is present, it suspends the current transaction and starts a new
one.

✅ Use Case:
When a method needs to execute independently from the caller’s transaction.
Useful for audit logging, sending emails, or handling retries.

✅ Example:
@Transactional(propagation = Propagation.REQUIRES_NEW)

public void methodB() {

// Always runs in a new transaction

✅ Scenario:
Caller Transaction Called Method Transaction Final Behavior
(REQUIRES_NEW)

Exists Suspends the caller’s Independent transaction


transaction, creates a new
one

Does not exist Creates a new transaction New transaction


✅ Rollback Impact:
If methodB fails, only its changes are rolled back (Caller transaction remains intact).
If the caller fails, methodB's transaction remains committed.

3. [Link]
✅ Behavior:
Requires an existing transaction; otherwise, it throws an exception.

✅ Use Case:
Use when a method must run inside an existing transaction.

✅ Example:
@Transactional(propagation = [Link])

public void methodC() {

// Will throw an exception if called without an existing transaction

✅ Scenario:
Caller Transaction Called Method Transaction Final Behavior
(MANDATORY)

Exists Joins existing transaction Runs normally

Does not exist Throws Error


TransactionRequiredException

✅ Rollback Impact:
If methodC throws an exception, everything rolls back.

4. [Link]
✅ Behavior:
If a transaction exists, it joins the transaction.
If no transaction exists, it runs without a transaction.

✅ Use Case:
Use when a method can work with or without a transaction (e.g., simple read operations).

✅ Example:
@Transactional(propagation = [Link])

public void methodD() {

// Executes within a transaction if available

✅ Scenario:
Caller Transaction Called Method Transaction Final Behavior
(SUPPORTS)

Exists Joins the existing transaction Transactional

Does not exist Runs without a transaction No rollback capability

✅ Rollback Impact:
If executed inside a transaction and fails, everything rolls back.
If executed outside a transaction, it won’t rollback automatically.

5. Propagation.NOT_SUPPORTED
✅ Behavior:
If a transaction exists, it suspends the transaction.
Runs without a transaction.

✅ Use Case:
Use when a method should not be part of a transaction (e.g., reporting queries, logging).

✅ Example:
@Transactional(propagation = Propagation.NOT_SUPPORTED)

public void methodE() {


// Runs without a transaction, even if the caller has one

✅ Scenario:
Caller Transaction Called Method Transaction Final Behavior
(NOT_SUPPORTED)

Exists Suspends caller’s Non-transactional


transaction, runs without one

Does not exist Runs normally without a No rollback capability


transaction

✅ Rollback Impact:
No rollback happens since no transaction exists.

6. [Link]
✅ Behavior:
If a transaction exists, it throws an exception.
If no transaction exists, it runs without a transaction.

✅ Use Case:
Use when a method must not run inside a transaction (e.g., performance-heavy tasks,
batch jobs).

✅ Example:
@Transactional(propagation = [Link])

public void methodF() {

// Will throw an exception if called inside a transaction

✅ Scenario:
Caller Transaction Called Method Final Behavior
Transaction (NEVER)

Exists Throws Error


IllegalTransactionState
Exception

Does not exist Runs normally Non-transactional

✅ Rollback Impact:
No rollback happens since no transaction exists.

7. [Link]
✅ Behavior:
Runs inside an existing transaction as a nested transaction.
If the parent transaction rolls back, the nested one also rolls back.
If the nested transaction fails, only its changes are rolled back, but the parent continues.

✅ Use Case:
Use when a sub-operation should rollback independently from the parent (e.g., saving
optional logs while main transaction continues).

✅ Example:
@Transactional(propagation = [Link])

public void methodG() {

// Runs inside a nested transaction

✅ Scenario:
Caller Transaction Called Method Final Behavior
Transaction (NESTED)

Exists Creates a savepoint Nested transaction


inside the existing
transaction

Does not exist Behaves like New transaction


REQUIRED (new
transaction)

✅ Rollback Impact:
If methodG fails, only its changes rollback.
If the caller fails, then everything rolls back.

Isolation Levels in @Transactional (Spring Boot + Spring Data JPA)

The isolation level determines how transaction integrity is maintained when multiple
transactions occur simultaneously. Spring allows setting the isolation level using
@Transactional with the isolation attribute.

Isolation Levels in Spring Boot

Spring provides the following isolation levels (mapped to JDBC standards):


Isolation Level Description Behavior

DEFAULT Uses the database's default isolation Varies depending on the database
level. (e.g., MySQL defaults to
REPEATABLE_READ, PostgreSQL to
READ_COMMITTED).

READ_UNCOMMITTED Allows dirty reads (one transaction Fast but risky (can read
can see uncommitted changes of uncommitted changes).
another transaction).

READ_COMMITTED Prevents dirty reads but allows non- Ensures only committed data is
repeatable reads and phantom read.
reads.

REPEATABLE_READ Prevents dirty and non-repeatable Ensures the same query within a
reads, but allows phantom reads. transaction returns the same result.

SERIALIZABLE Highest isolation level; prevents all Most strict but can cause
concurrency issues (dirty, non- performance issues due to locking.
repeatable, and phantom reads).

Transaction Issues in Database (Dirty Read, Phantom Read, Non-


Repeatable Read)
When multiple transactions operate concurrently, they may cause inconsistencies in the
data. The three main issues that occur due to concurrent transactions are:

1. Dirty Read
2. Non-Repeatable Read
3. Phantom Read
4.

1️⃣ Dirty Read (Occurs in READ_UNCOMMITTED)


A dirty read happens when a transaction reads data that has been modified by another
transaction but not yet committed. If the modifying transaction rolls back, the reading
transaction will have read incorrect data.

Example: Dirty Read

Transaction 1 (T1) - Updating data


Transaction 2 (T2) - Reading before commit

Transaction 1 (T1) - Rolls back the update

Now, Transaction 2 read incorrect data, which was later rolled back. This is called a dirty
read.

💡 Prevention: Use READ_COMMITTED, REPEATABLE_READ, or SERIALIZABLE.

2️⃣ Non-Repeatable Read (Occurs in READ_COMMITTED)


A non-repeatable read occurs when a transaction reads the same row twice and gets
different results because another transaction modified and committed the data in between.

Example: Non-Repeatable Read

Transaction 1 (T1) - First Read


Transaction 2 (T2) - Updates and Commits

Transaction 1 (T1) - Second Read

3️⃣ Phantom Read (Occurs in REPEATABLE_READ)


A phantom read occurs when a transaction reads a set of rows twice, but new rows are
inserted or deleted by another transaction in between, causing different results.

Example: Phantom Read

Transaction 1 (T1) - First Read


Transaction 2 (T2) - Inserts a New Employee

Transaction 1 (T1) - Second Read

The first and second read gave different row counts because new data was added in
between.

💡 Prevention: Use SERIALIZABLE (ensures no other transaction modifies the dataset).


Isolation Levels and Their Protection Against Issues

Isolation Level Prevents Dirty Prevents Non- Prevents Phantom


Read Repeatable Read Read

READ_UNCOMMITT ❌ No ❌ No ❌ No
ED

READ_COMMITTED ✅ Yes ❌ No ❌ No
REPEATABLE_READ ✅ Yes ✅ Yes ❌ No
SERIALIZABLE ✅ Yes ✅ Yes ✅ Yes
Summary

Issue What Happens? Example Prevention

Dirty Read Reads Reads balance READ_COMMITTED


uncommitted before or higher
changes commit/rollback

Non-Repeatable Reads different Balance changes REPEATABLE_READ


Read values for the same between two reads or SERIALIZABLE
row in a
transaction

Phantom Read Different number New rows SERIALIZABLE


of rows in two added/deleted
reads between reads

Using higher isolation levels ensures stronger consistency but may affect performance.
Choose the right isolation level based on your application's needs.

Recommended Isolation Levels Based on Use Cases

Scenario Recommended Isolation Level

High performance, occasional READ_UNCOMMITTED


inconsistencies are fine

Prevent dirty reads (most databases' READ_COMMITTED


default)

Ensures stable reads within a transaction REPEATABLE_READ

Strict consistency (bank transactions, SERIALIZABLE


booking systems)

Usage of @Transactional with Isolation Levels


You can specify the isolation level in the @Transactional annotation like this.

isolation level helps us to avoid dirty read, unrepeatable read and phantom ream problems

Explanation of Each Isolation Level in Detail

1️⃣ READ_UNCOMMITTED (Least Safe)


Transactions can read uncommitted changes made by other transactions.
May result in dirty reads (inconsistent data).
Rarely used in practice because of potential data integrity issues.

Example:
⚠️ Risk: If Transaction 1 rolls back, Transaction 2 read incorrect data.

2️⃣ READ_COMMITTED (Default in Many Databases)


Transactions can only read committed changes.
Dirty reads are prevented.
Non-repeatable reads and phantom reads can still occur.

Example:

✅ Safe from dirty reads, but data may change between reads.

3️⃣ REPEATABLE_READ
Prevents dirty reads and non-repeatable reads.
Ensures that the same query within a transaction always returns the same result.
Phantom reads can still occur.

Example:

4️⃣ SERIALIZABLE (Most Strict)


Prevents all concurrency issues (dirty reads, non-repeatable reads, and phantom reads).
Achieved by locking data to ensure full isolation.
Most expensive in terms of performance.

Example:

All concurrent transactions are executed one after another, ensuring full isolation.
No two transactions can modify or read the same data at the same time.

⚠️ Risk: Can reduce performance due to locking and high contention.

When to Use Which Isolation Level?

Use Case Recommended Isolation Level

High performance, occasional data READ_UNCOMMITTED


inconsistency is acceptable

General use case (default in many databases) READ_COMMITTED

Ensuring stable reads within a transaction REPEATABLE_READ

Full data integrity, avoiding all concurrency SERIALIZABLE


issues

You might also like