我在控制器的服务中调用以下方法,其中方法顶部没有@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被禁用
答案 0 :(得分:0)
基本上,使用“在视图中打开会话” /“在视图中打开实体管理器”模式时,这是可能的。
Spring默认情况下启用了“在视图中打开实体管理器”模式(即属性spring.jpa.open-in-view
设置为true
)。
此属性告诉Spring注册OpenEntityManagerInViewInterceptor
来达到目的。
UPD。
JPA不会对读取操作强制执行事务。这就是为什么select语句在没有@Transactional
的情况下起作用的原因。
如果用户未声明事务边界,则每个select语句将在单独的事务(自动提交模式)中执行-这就是JDBC处理这种情况的方式(即JDBC打开一个事务)。
JDBC在执行语句后立即关闭事务,并且不将该事务绑定到任何线程。