MySQL Transactions and ACID Properties

Learn MySQL Transactions and ACID Properties with practical examples, explanations, best practices, and real-world coding techniques.

What a transaction does

A transaction groups database operations into one logical unit. With a transactional engine such as InnoDB, an application can commit the unit when its required work succeeds or roll it back when a step fails. Transactions are essential when partial completion would leave an invalid business state—for example, an order header without its required line items or a transfer that debits one account but fails to credit another. A transaction makes database state changes coordinate, but it does not automatically validate whether the business operation itself is correct.

The ACID properties describe important transaction guarantees. Atomicity means the grouped work is treated as all-or-nothing. Consistency means constraints and application invariants should hold before and after the transaction. Isolation defines how concurrent transactions observe and affect each other. Durability means a committed transaction is retained according to the configured server and storage guarantees. ACID is not a setting that replaces schema design, application checks, backups, or operational configuration.

Start, commit, and roll back

START TRANSACTION;

UPDATE accounts
SET balance = balance - 50
WHERE account_id = 1
  AND balance >= 50;

SELECT ROW_COUNT() AS debit_rows;

-- Application verifies exactly one eligible account was updated.
-- Then it credits the destination and commits, or rolls back on failure.
COMMIT;

The example only shows the debit phase; a real transfer must check that exactly one row changed, credit the destination, and roll back if either step fails. Both account tables must use a transactional engine. Keep the transaction on one database connection from start to finish, especially when using a connection pool. If a network failure occurs during COMMIT, the application may not know whether the server committed; a retry strategy should use idempotency or a transaction identifier rather than blindly repeating a financial action.

Consistency requires domain rules

A transaction preserves the atomic grouping of statements, but a syntactically valid transaction can still perform the wrong calculation. Use constraints such as primary keys, foreign keys, unique keys, and supported check constraints to enforce durable data rules. Add application logic for business conditions that require context, such as a user's authorization or a workflow state transition. Validate rows affected and verify assumptions before committing. A successful COMMIT only means the server accepted the transaction; it does not prove that the user's intended operation was modeled correctly.

Some MySQL statements, especially many DDL statements, cause implicit commits. Mixing schema changes with ordinary DML inside a transaction can therefore produce unexpected boundaries. Consult version-specific behavior and use migrations for schema changes. Do not promise that arbitrary DDL can be rolled back because it appears between START TRANSACTION and ROLLBACK.

Isolation and concurrent operations

Isolation controls what a transaction sees when other sessions are changing the same data. InnoDB uses MVCC for consistent reads and locks for writes, but exact behavior depends on isolation level and statement type. If two orders attempt to reserve the last item, reading the quantity and then updating in separate unprotected steps can oversell inventory. A guarded update, locking read, or other atomic design may be required. Study isolation levels and locking and test with concurrent sessions.

Keep transactions short

Long-running transactions can retain locks and old row versions, delay cleanup, and increase contention. Do not wait for user input, call a remote service, or perform long CPU work while a transaction is open. Prepare required data first, execute the smallest necessary set of statements, and commit or roll back promptly. For large batch work, consider chunking it with explicit restart and consistency semantics rather than holding one transaction for hours.

Deadlocks can occur even when transactions are correct. InnoDB detects a deadlock and rolls back a victim transaction; applications need to recognize the specific transient error and may retry the whole idempotent unit a bounded number of times. Do not retry every database failure indiscriminately. See deadlocks and concurrency control.

Transactions in application code

In application code, always ensure error paths roll back and release the connection. Structure transaction handling so an exception cannot accidentally return a connection with an open transaction to the pool. Do not expose raw SQL errors to users; log diagnostic information safely and map known validation or conflict errors to appropriate responses. A database rollback cannot undo external side effects such as a sent email or completed payment call, so coordinate those operations with idempotency, an outbox, or another deliberate distributed workflow when needed.

Transactions provide a crucial boundary for related writes when paired with InnoDB and clear invariants. Test success, validation failure, deadlock, connection loss, and uncertain commit outcomes. Continue with constraints, isolation, and recovery planning.

Code Examples

Group related writes in one transaction

sql
START TRANSACTION;

UPDATE accounts
SET balance = balance - 50
WHERE account_id = 1
  AND balance >= 50;

-- Verify one row changed, then credit the destination.
UPDATE accounts
SET balance = balance + 50
WHERE account_id = 2;

COMMIT;
    

A real application must check the debit row count and roll back if either account update fails.

Roll back after a failed validation

sql
START TRANSACTION;
UPDATE inventory
SET quantity = quantity - 1
WHERE product_id = 42
  AND quantity > 0;

SELECT ROW_COUNT() AS rows_changed;
-- If rows_changed is not 1, issue:
ROLLBACK;
    

The application decides whether to commit or roll back based on the guarded update result.

Inspect the current isolation level

sql
SELECT @@transaction_isolation;
    

Isolation settings affect concurrent visibility; inspect the effective session value when diagnosing behavior.

Pro Tip

Do not report success until COMMIT succeeds, and design retries around idempotent operations because a lost connection can leave commit outcome uncertain.

🎨 IgKnight Docs

Master HTML, CSS, JS, Python, .NET and more with easy-to-follow lessons and practical code examples.

© 2025 IgKnight Learning Platform. All rights reserved.