服务层在 spring 中是否始终必须是事务性的?

Do service layer always must be transactional in spring?

我在 spring 中有非常简单的应用程序,包括 1 个模型 class 用于数据库 table、1 个 jpa 存储库 class 1 个服务和 1 个控制器 class .

我的服务 class 是:

@Transactional
@Service
public class SomeService {

    private ServiceRepository serviceRepository;

    @Autowired
    public serviceService(ServiceRepository serviceRepository) {
        this.serviceRepository = serviceRepository;
    }


    public void getServiceById(Long id) {
        Model model = serviceRepository.getOne(id);
        return....
    }

}

它正在使用@Transactional 注释。但如果我删除它,我会得到

org.hibernate.LazyInitializationException: could not initialize proxy

如果我不想要任何事务性方法或 class,为什么我必须使其成为事务性方法?

发生此异常是因为您尝试访问尚未在您的事务中加载的对象。

离开事务后,您将无法再从数据库加载对象。但交易不是强制性的。

我认为您有具有 OneToMany/ManyToMany 关系的对象是 lazyLoaded。因为您的服务不是事务性的,与数据库的连接已关闭,您无法再访问对象。

您有 2 个选择:

  • 为您的对象设置 Eager fetch(您的对象始终处于加载状态)。
  • 使您的服务具有事务性(对象将按需加载)。

您应该注意激活延迟加载(默认选项)时的性能问题。它是否与使用相关确实取决于您的业务逻辑,但最好不要对数据库进行多次访问。

您还可以查看实体图以进行高级自定义: https://www.baeldung.com/jpa-entity-graph

此外,在开发时,启用休眠 SQL 跟踪以查看后台发生的情况:https://www.mkyong.com/hibernate/hibernate-display-generated-sql-to-console-show_sql-format_sql-and-use_sql_comments/