【问题标题】:How to use Spring, Hibernate, MySQL ISAM with transactions?如何在事务中使用 Spring、Hibernate、MySQL ISAM?
【发布时间】:2025-12-06 10:45:01
【问题描述】:
我在一个小型个人项目中使用 Hibernate 和 Spring。好吧,还是这个领域的新手,所以想提出一些关于交易的基本问题。
看来我必须声明事务管理器并将DAO类注释为
@Transactional(传播 = Propagation.REQUIRED,只读 = false)。否则我会得到一些奇怪的异常,或者实体没有保存在数据库中。实际上是否必须使用事务?我不能在不使用它们的情况下将数据保存在数据库中(我认为 MySQL ISAM 表不支持事务),那么您将如何使用它们呢?
放置@Transactional 属性的最佳位置是什么?目前它在我的通用 HibernateDAO 超类中声明,可能是它可以达到的最深层次。我想那不是最好的地方。但如果将它向上移动,我最终会将它放在 Spring MVC 控制器中,这可能也是不合适的地方。到目前为止,还没有其他服务层,因为除了保存和提供数据库中的单词和定义之外,我什么都不做。
非常感谢
【问题讨论】:
标签:
java
mysql
hibernate
spring-mvc
transactions
【解决方案2】:
是的,您总是需要使用事务来使用 Hibernate 访问数据库(甚至实际上没有)。我只是不会使用 MyISAM,因为正如你所说,它不是事务数据库引擎。
放置@Transactional 注释的最佳位置是在您的功能服务上,在服务层中。要么你引入一个真正的服务层,要么你认为 DAO 层实际上就是你的服务层。但请注意,如果您的控制器必须使用 FooDAO 保存一个 foo ,并使用 BarDAO 保存一个 bar ,并且如果这两个插入应该以事务方式完成,那么您就有大问题了。这就是服务层如此重要的原因:它可以在单个事务中访问多个 DAO
【解决方案3】:
spring hibernate 事务管理器还负责为您管理休眠会话。如果您将 sessionFactory.getCurrentSession() api 与 spring hiberanteTranasactionManager 一起使用,spring 将负责在事务开始时打开会话并在事务结束后关闭它。
这使您的代码更清晰。您不必在代码中乱扔 openSession 和 closeSession。使用每个请求的会话方法而不是为每个休眠操作打开和关闭会话也是一个好主意。
正如您所提到的,将其放置在服务层是正确的位置 - 通过调用许多 DAO 方法来实现用例逻辑的类。如果您没有一个,则您正在从控制器执行多个 DAO 调用,或者您的 DAO 在需要时执行多个 db 操作。
如果你从一个控制器方法调用多个 DAO 方法,你应该把 @Transactional 放在控制器方法上。
如果您的 DAO 正在执行多个数据库操作,您应该将其置于 DAO 级别。
如果应用程序涉及非平凡逻辑(超出基本 CRUD),最好在此级别创建服务层和管理器事务。