【发布时间】:2018-06-02 06:38:32
【问题描述】:
我正在使用 Spring 数据 jpa 和 jdbc(使用 entityManager.unwrap(Session.class) )连接。
我的请求通过 3 种方法流动。第一 -> 第二 -> 第三。
第一个和第三个用@Transactional 注释。
在第一种和第二种方法中通过 JPA CRUD 存储库保存实体。
在第三种方法中,使用基本的 jdbc 查询来检索保存在第二种方法中的值。
正如我们所知,@Transaction 实体在 JPA 提交事务之前不会提交到数据库。
我在第二种方法中也使用了 saveAndFlush,但在方法 3 中使用 jdbc 查询时看不到检索更新的值。
第一种方法 - update()
@Transactional
@Override
public ApiResponse update(RequestInput input) {
ApiResponse response = doRestOfWork(input); // calling 2nd method
// .... some other entity save....
}
第二种方法 - doRestOfWork():设置 status=true 并调用 saveAndFlush 方法
@Override
public ApiResponse doRestOfWork(Request request) {
Insight insight = insightRepository.findOne(request.getTypeId());
insight.setStatus(true);
insightRepository.saveAndFlush(insight);
processOperation(); // calling 3rd method
}
第三种方法 - processOperation():通过 jdbc 连接检索更新的状态值。
@Transactional
public void processOperation() {
Connection conn = null;
SessionImplementor sessionImpl = (SessionImplementor) entityManager.unwrap(Session.class);
try {
conn = sessionImpl.getJdbcConnectionAccess().obtainConnection();
Connection conn = null;
String stmt = "SELECT status from insight";
PreparedStatement ps = conn.prepareStatement(stmt);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
boolean value = rs.getBoolean(status); // returning false, i want this to return true as already set true in 2nd method and called saveAndFlush
}
} catch (SQLException ex) {
} finally {
JdbcUtility.closeResources(conn, ps, rs);
}
}
InsightRepository 正在扩展 JpaRepository
@Repository
public interface InsightRepository extends JpaRepository<Insight, Long> {}
我想在方法 3 中更新状态值(布尔值 true - 在方法 2 中更新)。 如何做到这一点?
更新
我搜索了很多,不认为如果一个方法用 @Transactional 注释,那么你可以在完成 JPA 事务之前提交更改。所以解决办法是去掉@Transactional注解,如果想控制JPA事务,使用entityManager.getTransaction()。
【问题讨论】:
-
为什么不将第二个方法注释为@Transactional,而不是第三个?只做
select不需要显式事务。另外:我怀疑saveAndFlush提交了更改。 -
因为方法 3 有其他获取和更新 JPA 事务。为简单起见,我只添加了一个选择操作。 saveAndFlush 没有提交事务。这就是我的问题是如何在第二种方法中提交更改。
-
您可以同时注释两者。第三种方法会超过第一个交易。
-
我搜索了很多,不认为如果一个方法用 Transactional 注释,那么你可以在完成 JPA 事务之前提交更改。所以解决办法是要么去掉 Transactional 注解,要么使用 entityManager.getTransaction() 来控制 JPA 事务。
-
如果方法 3 使用与方法 2 相同的事务,尽管更新尚未提交,但它会看到更新。如果您真的想要在进入方法 3 之前提交,而不是将方法 2 的更新代码提取到自己的子方法中,该子方法被注释为 Transactional。
标签: java hibernate jdbc spring-data-jpa spring-jdbc