fix(batch): writeTo @Transactional 제거 + end_time Timestamp 객체 전달

검증 전 선제 보강 2건.

1) BatchExecutor.writeTo 의 @Transactional 제거
   - 같은 클래스 내부 호출(execute → writeTo)이라 Spring AOP 가 우회되어 어차피 안 걸림
   - batch 의 정상 동작은 row 단위 독립 commit (일부 실패해도 다른 row 는 살아야 함).
     vexplor_rps 도 동일 패턴

2) BatchManagementService.executeBatchConfig 의 end_time 을 Timestamp 객체로 직접 전달
   - 기존: Timestamp.toString() 으로 변환 후 #{end_time}::timestamp 캐스트
   - 신규: Timestamp 객체 그대로 → PostgreSQL JDBC 가 timestamp 자동 변환,
     mapper 의 ::timestamp 캐스트는 noop

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
hjjeong
2026-05-13 11:50:49 +09:00
parent 6f8461a533
commit d592547242
2 changed files with 5 additions and 3 deletions
@@ -6,7 +6,6 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.sql.Connection;
import java.sql.PreparedStatement;
@@ -222,7 +221,8 @@ public class BatchExecutor {
// ── TO 저장 ────────────────────────────────────────────────────────────
@Transactional
// 트랜잭션은 의도적으로 걸지 않음 — batch 의 정상 동작은 row 단위 독립 commit.
// 일부 row 가 실패해도 다른 row 는 살아야 successCount/failedCount 집계가 의미 있음.
public WriteResult writeTo(
Map<String, Object> firstMapping,
List<Map<String, Object>> rows,
@@ -161,7 +161,9 @@ public class BatchManagementService extends BaseService {
Map<String, Object> updateLog = new LinkedHashMap<>();
updateLog.put("id", logId);
updateLog.put("execution_status", status);
updateLog.put("end_time", new java.sql.Timestamp(System.currentTimeMillis()).toString());
// PostgreSQL JDBC 드라이버가 Timestamp → timestamp 자동 변환.
// mapper 의 #{end_time}::timestamp 캐스트는 noop 으로 안전.
updateLog.put("end_time", new java.sql.Timestamp(System.currentTimeMillis()));
updateLog.put("duration_ms", duration);
updateLog.put("total_records", execResult != null ? execResult.totalRecords : 0);
updateLog.put("success_records", execResult != null ? execResult.successRecords : 0);