Why Spring @Transactional Commits After Unlock and How to Prevent Over‑selling

This article explores the subtle timing of Spring transaction start and commit relative to lock/unlock, demonstrates how improper ordering can cause over‑selling in high‑concurrency scenarios, and provides debugging techniques and practical solutions to ensure atomicity and correct rollback behavior.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
Why Spring @Transactional Commits After Unlock and How to Prevent Over‑selling

Transaction Start Timing

A method annotated with @Transactional performs two main actions: query product stock from the database and, if stock exists, decrement the stock and insert an order record. Both actions must be atomic.

In a high‑concurrency environment, the method is wrapped with a lock to ensure only one thread executes the stock‑decrement logic at a time. MySQL uses the REPEATABLE READ isolation level by default.

If the transaction commits before the lock is released, the operation is safe. If the transaction commits after unlock, another thread may read stale stock data, leading to over‑selling.

Finding the Answer

The real transaction start point is inside

org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin

, where the JDBC connection is switched to manual commit:

Switching JDBC Connection [...] to manual commit

This only sets autoCommit to false; the transaction actually starts when the first SQL statement is executed after the lock.

Spring uses the second way of starting a transaction (disabling auto‑commit). The con.setAutoCommit(false) call merely prepares the connection.

Before or After

When the lock is released before the transaction commits, another thread can read the unchanged stock value, causing duplicate orders. The article shows a concrete example with two threads A and B where A releases the lock before committing, B reads the old stock, and both place orders.

Therefore, in the presented code, the transaction commit occurs after unlock, which is the root cause of the over‑selling problem.

Solution

Correct usage of the lock should enclose the entire transaction, guaranteeing that the commit happens before the lock is released. Alternatives include:

Using a distributed lock in clustered environments.

Setting the isolation level to SERIALIZABLE to avoid phantom reads.

Switching to programmatic transaction management for explicit control.

Adjusting @Transactional attributes (e.g., isolation, propagation) to match the concurrency model.

Debugging tips: set breakpoints on DataSourceTransactionManager#doBegin, TransactionAspectSupport#invokeWithinTransaction, and the JDBC driver’s sendQueryString to observe when the transaction actually starts and commits.

Rollback‑only

Spring marks a transaction as rollback‑only when an exception matching the rollback rules is thrown. By default, RuntimeException and Error trigger a rollback. The decision is made in RuleBasedTransactionAttribute#rollbackOn, which checks the exception type against RollbackRuleAttribute and NoRollbackRuleAttribute.

If a transaction is marked rollback‑only, the commit phase is skipped and a

Transaction rolled back because it has been marked as rollback‑only

exception is logged.

Understanding propagation (default REQUIRED) helps avoid unexpected rollbacks when nested transactions are involved.

Overall, the article demonstrates how to locate the exact points in Spring’s source code that control transaction start, commit, and rollback, and how to align locking strategies with transaction boundaries to prevent data inconsistency.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavatransactiondatabaseconcurrencyspringLock
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.