Quarkus에서 배치 실행을 위해 프로그래밍 방식으로 Hibernate Commit 제어
배치 실행 중 커밋이 많은 문제
배치 실행에서 엄청난 양의 데이터를 처리해야 하는 경우 Hibernate가 수행하는 커밋 수를 제어하는 것이 중요합니다.
커밋은 가장 비용이 많이 드는 데이터베이스 작업 중 하나입니다.
@Transactional 주석 사용
Quarkus에서는
@Transactional
주석을 사용하여 커밋 실행을 제어할 수 있습니다. @Transactional
주석이 달린 메서드가 성공적으로 완료되면 Hibernate는 하나의 커밋을 데이터베이스로 보냅니다.import javax.transaction.Transactional;
//
@Transactional(rollbackOn = Exception.class)
public void processClientOrders(Client client) {
client.updateOrders();
client.insertHistory();
client.updateClient();
}
위의 예에서 processClientOrders()가 완료되면 Hibernate는 하나의 커밋을 데이터베이스로 보냅니다.
배치 실행을 제어하기 위해 @Transactional 주석을 사용하는 데 어려움이 있음
배치 실행에서는 처리된 항목의 양이나 커밋 사이의 시간을 사용하여 커밋 수를 제어하는 것이 좋습니다.
내 관점에서 특히 커밋 사이의 시간을 제어하기 위해 @Transactional 주석을 사용하여 이것을 제어하기가 약간 어렵습니다.
프로그래밍 방식으로 커밋 실행
여기서 제공하려는 기여는 프로그래밍 방식을 사용하여 커밋을 제어하는 한 가지 아이디어입니다.
애플리케이션에서 커밋 매개변수 정의
이 항목은 필수는 아니지만 좋은 생각이라고 생각합니다. 이 접근 방식을 사용하면 배포 시 값을 조정할 수 있습니다.
application.properties
에서 두 개의 매개변수를 정의합니다.# Minimum quantity of items processed to execute commit
app.quantity.of.items.to.commit=1000
# Minimum quantity of time (milliseconds) to execute commit
app.quantity.of.time.ms.to.commit=1000
프로그래밍 방식으로 트랜잭션 제어
트랜잭션을 프로그래밍 방식으로 제어하려면
UserTransaction
를 삽입한 다음 수동으로 트랜잭션을 시작하고 커밋해야 합니다.@Inject
UserTransaction transaction;
@ConfigProperty(name = "app.quantity.of.items.to.commit")
int quantityItemsCommit;
@ConfigProperty(name = "app.quantity.of.time.ms.to.commit")
int quantityTimeCommit;
public void batchProcess(List<Client> listOfClients)
throws SystemException,NotSupportedException,
SecurityException, IllegalStateException,
RollbackException, HeuristicMixedException,
HeuristicRollbackException {
var beforeCommit = Instant.now();
var quantityOfClientsPendingCommit = 0;
transaction.begin();
for (Client client : listOfClients ) {
processClientOrders(client);
var now = Instant.now();
var delay = Duration.between(beforeCommit, now).toMillis();
if (++quantityOfClientsPendingCommit >= quantityItemsCommit
|| delay >= quantityTimeCommit) {
transaction.commit();
transaction.begin();
beforeCommit = Instant.now();
quantityOfClientsPendingCommit = 0;
}
}
transaction.commit();
}
private void processClientOrders(Client client) {
client.updateOrders();
client.insertHistory();
client.updateClient();
}
위의 코드는 처리되는 클라이언트의 양이 제한보다 크거나 같거나 마지막 커밋 후 시간이 제한보다 크거나 같을 때 커밋을 실행합니다.
최종 단어
이 기사가 뭔가를 추가할 수 있기를 바라며, 내가 한 실수를 발견하거나 이 개념을 개선할 아이디어가 있으면 의견을 말하십시오.
학점
Stack Overflow post about calculating time in milliseconds
Red Hat documentation about Managing JTA transactions programmatically
Reference
이 문제에 관하여(Quarkus에서 배치 실행을 위해 프로그래밍 방식으로 Hibernate Commit 제어), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/felipewind/controlling-hibernate-commit-programmatically-for-batch-execution-on-quarkus-3fhk텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)