全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-18 6 分钟 ✍️ juanwangdev

事务的基本概念与ACID属性

事务是一组数据库操作的逻辑单元,要么全部成功,要么全部失败。

什么是事务

Java
// 转账场景:A向B转账100元
// 事务包含两个操作,必须同时成功或同时失败
BEGIN TRANSACTION;
UPDATE account SET balance = balance - 100 WHERE id = 'A';  -- A扣100
UPDATE account SET balance = balance + 100 WHERE id = 'B';  -- B加100
COMMIT;  -- 或 ROLLBACK;

事务将多个操作绑定为一个原子单元,保证数据一致性。

ACID四大特性

原子性(Atomicity)

事务是不可分割的执行单元,要么全部完成,要么全部不执行。

Java
┌─────────────────────────────────────┐
│              事务开始                 │
├─────────────────────────────────────┤
│  操作1: A账户扣款 ✓                   │
│  操作2: B账户加款 ✗ (失败)           │
├─────────────────────────────────────┤
│  结果: 全部回滚,A恢复原状            │
└─────────────────────────────────────┘
Java
@Transactional
public void transfer(Long fromId, Long toId, BigDecimal amount) {
    accountDao.decrease(fromId, amount);
    // 如果此处抛异常,上面的扣款会回滚
    accountDao.increase(toId, amount);
}

一致性(Consistency)

事务执行前后,数据库从一个一致状态转换到另一个一致状态。

Java
转账前:
A余额: 500元, B余额: 300元, 总额: 800元

转账后:
A余额: 400元, B余额: 400元, 总额: 800元  ✓ 一致

如果A扣款成功但B加款失败:
A余额: 400元, B余额: 300元, 总额: 700元  ✗ 不一致
事务回滚保证不会出现这种情况
Java
// 约束检查保证一致性
@Entity
public class Account {
    @Column(nullable = false)
    private BigDecimal balance;

    @PreUpdate
    public void validate() {
        if (balance.compareTo(BigDecimal.ZERO) < 0) {
            throw new RuntimeException("余额不能为负");
        }
    }
}

隔离性(Isolation)

并发事务之间相互隔离,一个事务的中间状态对其他事务不可见。

Java
时间线:
┌─────────────────────────────────────────────────┐
│  事务A: 开始 ──────────────────────────── 提交   │
│          │                              │       │
│  事务B:  │─ 开始 ───────────── 提交 ────│─→     │
│          │   (读不到A的中间状态)         │       │
└─────────────────────────────────────────────────┘
隔离级别脏读不可重复读幻读
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE
text
@Transactional(isolation = Isolation.READ_COMMITTED)
public Account getAccount(Long id) {
    return accountDao.findById(id);
}

持久性(Durability)

事务一旦提交,对数据的修改是永久性的,即使系统崩溃也不会丢失。

text
事务提交流程:
┌──────────────┐    ┌──────────────┐    ┌──────────────┐
│   内存数据    │ → │   写入日志    │ → │   刷入磁盘    │
│   修改完成    │    │   (redo log)  │    │   (持久化)   │
└──────────────┘    └──────────────┘    └──────────────┘
                           ↓
                    即使崩溃也能恢复

通过redo log和undo log保证持久性,数据库崩溃后可恢复已提交的事务。

ACID的关系

text
        ┌─────────────────────┐
        │       一致性          │
        │   (最终目标)          │
        └─────────────────────┘
                 ↑
    ┌────────────┼────────────┐
    │            │            │
┌───┴───┐   ┌───┴───┐   ┌───┴───┐
│原子性  │   │隔离性  │   │持久性  │
│(保证)  │   │(保证)  │   │(保证)  │
└───────┘   └───────┘   └───────┘
  • 原子性保证操作不可分割
  • 隔离性保证并发不干扰
  • 持久性保证提交不丢失
  • 三者共同保证一致性

Spring事务与ACID

text
@Service
public class OrderService {

    // Spring @Transactional 保证ACID
    @Transactional
    public void createOrder(Order order) {
        // 原子性: 整个方法要么成功要么回滚
        orderDao.insert(order);

        // 一致性: 库存不能为负
        inventoryService.decrease(order.getProductId(), order.getQuantity());

        // 隔离性: 配置隔离级别控制
        // 持久性: 提交后数据持久化
    }
}

事务边界问题

text
// 错误:事务边界不清晰
public void process() {
    step1();  // 事务1
    step2();  // 事务2
    // step1成功step2失败,无法保证整体原子性
}

// 正确:统一事务边界
@Transactional
public void process() {
    step1();
    step2();
    // 要么都成功,要么都回滚
}

要点总结

  • 原子性:操作不可分割,要么全成功要么全回滚
  • 一致性:数据从一个有效状态转换到另一个有效状态
  • 隔离性:并发事务之间相互隔离
  • 持久性:提交后数据永久保存
  • @Transactional注解实现声明式事务管理
  • 合理设置事务边界是保证ACID的关键

📝 发现内容有误?点击此处直接编辑

← 上一篇 事务传播行为
下一篇 → 事务超时与回滚规则
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库