Databases 10 min read

Resolving Duplicate Income Splitting in a Financial System: Transaction Isolation, Spring Propagation, and Redis Lock

This article analyzes a financial system's duplicate income‑splitting bug caused by concurrent transactions, explains how MySQL isolation levels and Spring transaction propagation contributed to dirty reads, and presents two corrective approaches—adjusting transaction propagation and repositioning Redis locks—to ensure reliable data consistency.

Beike Product & Technology
Beike Product & Technology
Beike Product & Technology
Resolving Duplicate Income Splitting in a Financial System: Transaction Isolation, Spring Propagation, and Redis Lock

The financial system incorrectly split two incoming payments of ¥2000 and ¥3000, resulting in duplicated allocation of the first amount; both single‑payment and multi‑payment scenarios should have produced the same split of ¥2000 and ¥3000.

Initial investigation revealed that the two payments were processed by separate processes, each reading the same "pending" and "allocated" details, leading to a classic dirty‑read problem.

To address concurrency issues, the article reviews MySQL isolation levels—Read Uncommitted, Read Committed, Repeatable Read, and Serializable—highlighting which anomalies each level can prevent.

It then examines Spring's transaction propagation mechanisms, noting that the default PROPAGATION_REQUIRED caused the inner transaction to be ineffective, so the Redis lock only protected the outer transaction, allowing concurrent execution.

Two remediation strategies are proposed:

Change the propagation to PROPAGATION_REQUIRES_NEW so the inner transaction commits independently before the outer transaction releases the lock.

Move the Redis lock outside the transactional method to ensure the lock controls the entire operation.

Code examples illustrate the original and revised implementations, showing the @Transactional annotations and lock usage before and after the changes.

Finally, the article summarizes that proper transaction isolation, correct propagation settings, and appropriate lock placement are essential for preventing dirty reads and ensuring data integrity in high‑concurrency backend systems.

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.

transactiondatabaseredisspringmysql
Beike Product & Technology
Written by

Beike Product & Technology

As Beike's official product and technology account, we are committed to building a platform for sharing Beike's product and technology insights, targeting internet/O2O developers and product professionals. We share high-quality original articles, tech salon events, and recruitment information weekly. Welcome to follow us.

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.