【问题标题】:@PersistenceContext entitymanager working without transaction@PersistenceContext 实体管理器在没有事务的情况下工作
【发布时间】:2018-10-23 10:00:45
【问题描述】:

我正在从控制器调用以下服务方法,其中方法顶部没有@Transnational:

@Override
public void test1(Pageable pageable) {
    {
        Query query =entityManager.createQuery("SELECT U from User U",User.class);
        List<User> users=query.getResultList();
        User user=new User();
        user.setName("hello");
        user.setLastName("hello");
         entityManager.persist(user);
    }
}

我很困惑它是否有效,结果在方法结束时提交,实体管理器注入服务:

@PersistenceContext
private EntityManager entityManager;

谁能解释如何在没有跨国的情况下创建交易?


更新: 我的错误是我在界面上使用@Transactional 而没有注意到它。但是选择查询如何工作?会话何时创建? spring.jpa.open-in-view 被禁用

【问题讨论】:

    标签: spring hibernate spring-boot jpa hibernate-entitymanager


    【解决方案1】:

    基本上,当使用 Open Session In View / Open Entity Manager In View 模式时,这是可能的。

    Spring 默认启用在视图中打开实体管理器模式(即属性 spring.jpa.open-in-view 设置为 true)。

    这个属性告诉 Spring 注册 OpenEntityManagerInViewInterceptor 就可以了。

    UPD。

    JPA 不对读取操作强制执行事务。这就是为什么 select 语句在没有 @Transactional 的情况下有效的原因。

    如果用户没有声明事务边界,那么每个 select 语句都将在单独的事务中执行(自动提交模式)——这就是 JDBC 处理这种情况的方式(即 JDBC 打开一个事务)。

    JDBC 在语句执行后立即关闭事务并且不将此事务绑定到任何线程。

    【讨论】:

    • 不,我禁用了它:)
    • 更新了我在界面上缺少事务,但即使没有事务,选择查询也能正常工作,什么时候为它创建会话?
    • 如果用户没有声明事务边界,那么每条语句都会在一个单独的事务中执行(自动提交模式),那么如果语句在事务中运行,为什么持久化不起作用?例如。 :当前线程没有具有实际事务的EntityManager
    • 因为 JDBC 在“select”语句执行后立即关闭事务。所以事务只为“选择”打开,没有人将此事务绑定到当前线程
    • 是的,事务只为“读”操作打开,JDBC收到结果后立即关闭该事务
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    相关资源
    最近更新 更多