java - 如何在 Spring 事务之外执行 JPA 代码
问题描述
我想优化只读查询,所以我想在事务之外执行 JPQL 查询,这样从 JPQL 返回的实体将不会在当前持久性上下文中进行管理(为了节省脏检查的成本和不必要的管理这些实体以节省 2X 大小在持久性上下文中)。
我在下面尝试过,
@Repository
public class CustomPostRepository {
@Autowired
private EmployeeRepository employeeRepository;
@Transactional
public void foo() {
// Some other transactional code (read-write) here ...
final TransactionStatus transactionStatus = TransactionAspectSupport.currentTransactionStatus(); // returns current active transaction
System.out.println("transactionStatus.isNewTransaction() = " + transactionStatus.isNewTransaction()); // returns TRUE
List<Post> posts = employeeRepository.bar();
// Some other code here...
}
}
@Repository
public class CustomJpaEmployeeDao implements EmployeeRepository {
@PersistenceContext
private EntityManager em;
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public List<Post> bar() {
// Ideally this method should throw Exception, as transaction is expected to be suspended (not exists here)
final TransactionStatus transactionStatus = TransactionAspectSupport.currentTransactionStatus();
final List<Post> post = em.createNamedQuery("Post.findAllForReporing", Post.class).getResultList();
System.out.println("entityManager.contains(post) = " + em.contains(post.get(0))); // returns true, which should be false
return post;
}
}
呼叫者,
@Test
public void jpqlTest() {
customPostRepository.foo();
}
我想EmployeeRepository#bar
在事务之外执行(由 C 创建ustomPostRepository#bar
),但Propagation.NOT_SUPPORTED
不工作,所有从 JPQL 中选择的实体都在当前持久性上下文中进行管理。
那么,有什么办法可以避免管理这些实体或在事务之外执行代码呢?或者这里缺少什么?
解决方案
您应该删除@Transactional
注释。在这种情况下,除非方法本身不 throw ,否则它不会产生影响LazyInitializationException
。如果存在需要事务的情况,则必须为它创建一个单独的方法/从同一个 bean 调用它,这样就不会创建代理。
EntityManager#contains
也不检查进程是否在事务中运行或实体被脏检查。
如果您不想/不能更改这些方法,请使用EntityManager#detach
.
推荐阅读
- vb.net - 我怎样才能使这项工作?单击按钮时,我无法添加文本框值,然后在 textbox3 上显示
- node.js - 如果语句不能正常工作 discord.js
- html - 如何在运行时传递可由 html 代码选择的参数
- java - Thymeleaf 和 SpringBoot 的 NoSuchMessageException
- swift - 楼梯问题 Swift 打印“#” n 和 n-1 次
- catboost - 在 catboostclassifier 中使用 class_weights
- apache-storm - 使用状态索引在 Stormcrawler 上运行多个拓扑
- javascript - For循环仅打印最后一次迭代
- azure - Azure 流分析作业 - 固定 1 小时窗口内的累计金额
- ios - 有什么方法可以避免 SwiftUI GeometryReader 阻止嵌套视图在列表中增长?