【发布时间】:2018-03-20 16:04:59
【问题描述】:
我正在通过使用 Hibernate 和 EntityManager 的方法执行更新。
这个更新方法被多次调用(在一个循环内)。
好像我第一次执行它时,它锁定了表并且没有释放它。
在关闭应用程序后尝试通过 SQL Developer 更新表时,我看到表仍被锁定,因为更新挂起。
您认为如何解决这个问题?如果您需要更多信息,请告诉我。
类
@Repository
@Transactional(propagation = REQUIRES_NEW)
public class YirInfoRepository {
@Autowired
EntityManager entityManager;
@Transactional(propagation = REQUIRES_NEW)
public void setSent(String id) {
String query = "UPDATE_QUERY";
Query nativeQuery = entityManager.createNativeQuery(String.format(query, id));
nativeQuery.executeUpdate();
}
}
更新
等了一个多小时后,我再次启动了应用程序,它运行良好,但现在又挂了。
更新 2 -- 我将给予任何帮助我解决此问题的人最大的赏金
在另一个地方,我使用了应用程序管理的实体管理器,但它仍然给我同样类型的错误。
public void fillYirInfo() {
File inputFile = new File("path");
try (InputStream inputStream = new FileInputStream(inputFile);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {
bufferedReader.lines().skip(1).limit(20).forEach(line -> {
String[] data = line.split(",");
String rnr = data[0];
String linked = data[1];
String email = data.length > 2 ? data[2] : "";
String insuredId = insuredPeopleRepository.getInsuredIdFromNationalId(rnr);
int modifiedCounter = 0;
if (!isNullOrEmpty(insuredId)) {
EntityManager entityManager = emf.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
Query nativeQuery = entityManager.createNativeQuery(
"QUERY"
);
transaction.begin();
nativeQuery.executeUpdate();
entityManager.flush();
transaction.commit();
entityManager.close();
}
System.out.println(modifiedCounter + " rows modified");
});
} catch (IOException e) {
e.printStackTrace();
}
}
【问题讨论】:
-
看起来您没有提交交易。不知道如何在 Hibernate 中做到这一点。 Oracle 中的锁定是按行级别完成的,除非您通过 DDL 锁定整个对象,或者具有排他锁。
-
@FábioGalera 据我了解,这是一个容器管理的事务,因此它应该在方法完成时由容器自动提交。
-
@FábioGalera 奇怪的是更新是在不同的行上进行的。
-
你为什么在类和方法级别都使用@Transactional? stackoverflow.com/questions/23132822/…
-
另外,本地运行更新查询并不是使用 Hibernate/JPA 的首选方式。您应该从数据库中加载实体,在您的 Java 代码中对其进行变异,只要这是在事务中完成的,Hibernate 将确保在事务提交时将更改写入数据库。直接进行更新可能会弄乱 Hibernate 的缓存,这可能会导致奇怪的行为。
标签: spring oracle hibernate deadlock spring-transactions