温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java DAO 事务怎么控制才好

发布时间:2026-10-26 04:31:48 来源:亿速云 阅读:96 作者:小樊 栏目:编程语言

在 Java 里,DAO 层到底要不要控制事务,以及怎么控制才“好”,核心原则是:

事务应该在“业务边界”控制,而不是在 DAO 层控制

下面分层说清楚。


一、最推荐的做法(主流 & 正确姿势)

✅ DAO 只做数据访问,事务放在 Service 层

@Service
public class OrderService {

    @Transactional
    public void createOrder(Order order) {
        orderDao.insert(order);
        stockDao.decrease(order.getProductId());
        // 任一失败,整体回滚
    }
}
@Repository
public class OrderDao {
    public void insert(Order order) {
        // 只写 SQL
    }
}

为什么这样好?

  • 事务边界 = 业务边界
  • 一个 Service 方法可能调用多个 DAO
  • DAO 不知道“整体业务是否要回滚”
  • 更容易做单元测试

✅ 这是 Spring 项目最推荐的方式


二、DAO 层“不要”做的事

❌ 在 DAO 里:

public void insert(Order order) {
    Connection conn = dataSource.getConnection();
    conn.setAutoCommit(false);
    try {
        // ...
        conn.commit();
    } catch {
        conn.rollback();
    }
}

问题:

  • 多个 DAO 无法组成同一事务
  • 难以扩展(分布式、读写分离)
  • 和 Spring 事务机制冲突

三、如果你“必须”在 DAO 控制事务(极不推荐)

只在非 Spring / 老系统 / 工具类中:

try (Connection conn = dataSource.getConnection()) {
    conn.setAutoCommit(false);
    // DAO 操作
    conn.commit();
} catch (Exception e) {
    conn.rollback();
}

⚠️ 仅限:

  • 脚本
  • 批处理
  • 非业务系统

四、Spring 事务控制的最佳实践

1️⃣ 使用 @Transactional

@Transactional(
    propagation = Propagation.REQUIRED,
    isolation = Isolation.READ_COMMITTED,
    rollbackFor = Exception.class
)

2️⃣ 注意坑

❗ 方法必须是 public
❗ 自调用(同类方法调用)事务失效
❗ 默认只回滚 RuntimeException


五、多 DAO 共享事务的原理

Spring 用 ThreadLocal + AOP:

Service(Transaction)
 ├─ DAO1 (同一 Connection)
 ├─ DAO2 (同一 Connection)

只要:

  • 使用同一个 DataSource
  • 使用 Spring 管理的事务

✅ 自动共享连接


六、简单总结一句话

DAO 不控制事务,Service 用 @Transactional 控制事务,才是最干净、可维护的做法。

如果你愿意,我可以:

  • 给你 Spring Boot 完整示例
  • 讲 事务传播行为
  • 讲 多数据源 / 分布式事务
  • 看你现在用的是 MyBatis / JPA / JDBC

你是用的哪种?

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手