我正在使用Spring数据jpa和jdbc(使用entityManager.unwrap(Session.class))连接。
我的请求流经3方法。第1 - >第二 - >第三
第1和第3个用@Transactional注释
在第一和第二方法中通过JPA CRUD存储库保存实体
在第三种方法中使用基本的jdbc查询来检索第二种方法中保存的值
正如我们在@Transaction中所知,在JPA提交事务之前,实体不会提交到数据库
我在第二种方法中也使用了saveAndFlush,但是看不到使用jdbc查询在方法3中检索更新的值。
第一种方法 - 更新()
@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事务之前提交更改。因此,如果要控制JPA事务,解决方案是删除@Transactional注释并使用entityManager.getTransaction()。
答案 0 :(得分:0)
如果您想控制交易,请不要使用@Transactional
em; //entityManager
Transaction tx=em.getTransaction();
try{
tx.begin();
//do work
tx.commit(); // comminted transaction
// start another transaction if you need to, doo more work etc.
...
}
这是使用JPA进行原子操作的最基本和最基本的代码块。
此外,没有必要unwrap
实体经理,使用纯JPA。通过展开,您将当前实现绑定到JPA提供程序,这与JPA从底层JPA实现提供程序的独立性概念相反。换句话说,如果出于某种原因,Spring会将其JPA实现从Hibrnate更改为例如,它将停止工作。的EclipseLink。
答案 1 :(得分:0)
使用与第二种方法不同的bean中的@Transactional(propagation = Propagation.REQUIRES_NEW)
注释创建一个方法(第四种方法)进行更新,并将第二种方法更改为调用第四种方法,如下所示:
@Component //or Service etc..
public class AnotherBean{
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void doUpdateWork(Request request){
Insight insight = insightRepository.findOne(request.getTypeId());
insight.setStatus(true);
insightRepository.save(insight);
}
}
和
@Override
public ApiResponse doRestOfWork(Request request) {
anotherBean.doUpdateWork(request);
processOperation(); // calling 3rd method
}