feat(webstatement): optimalkan saveBatch pada ProcessStmtEntryDataJob
- **Perubahan Mekanisme Simpan Data:**
- Mengganti pendekatan `delete` dan `insert` dengan `updateOrCreate` untuk mencegah duplicate key error.
- Menambahkan transaksi database (`DB::beginTransaction()` dan `DB::commit()`) untuk memastikan konsistensi data.
- Menambahkan logging pada awal dan akhir proses untuk memantau jumlah record yang berhasil diproses.
- **Penanganan Error:**
- Menambahkan rollback transaksi (`DB::rollback()`) pada exception untuk menghindari data korup.
- Logging eror ditingkatkan dengan menampilkan pesan dan trace exception secara rinci.
- **Optimasi Loop:**
- Refinement looping pada `entryBatch` dengan menerapkan chunking untuk efisiensi memori.
- Proses setiap record menggunakan `updateOrCreate` guna mengurangi overhead penghapusan data secara manual.
- **Peningkatan Logging:**
- Menambahkan informasi log yang mencakup:
- Proses awal dan akhir dari `saveBatch`.
- Jumlah record yang diproses secara sukses.
- Error yang terjadi selama proses berlangsung.
- **Dokumentasi dan Komentar:**
- Menambahkan penjelasan detil pada method `saveBatch` untuk memperjelas logika baru.
- Penyempurnaan komentar agar mencerminkan proses terkini dengan jelas.
Perubahan ini meningkatkan efisiensi dan keandalan proses penyimpanan data batch dengan mengurangi risiko konflik pada database serta memastikan rollback pada situasi error.
Signed-off-by: Daeng Deni Mardaeni <ddeni05@gmail.com>
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
namespace Modules\Webstatement\Jobs;
|
||||
|
||||
use Exception;
|
||||
@@ -184,33 +186,53 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* Save batched records to the database
|
||||
* Simpan batch data ke database menggunakan updateOrCreate
|
||||
* untuk menghindari error unique constraint
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function saveBatch()
|
||||
: void
|
||||
private function saveBatch(): void
|
||||
{
|
||||
Log::info('Memulai proses saveBatch dengan updateOrCreate');
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
if (!empty($this->entryBatch)) {
|
||||
$totalProcessed = 0;
|
||||
|
||||
// Process in smaller chunks for better memory management
|
||||
foreach ($this->entryBatch as $entry) {
|
||||
// Extract all stmt_entry_ids from the current chunk
|
||||
$entryIds = array_column($entry, 'stmt_entry_id');
|
||||
foreach ($this->entryBatch as $entryChunk) {
|
||||
foreach ($entryChunk as $entryData) {
|
||||
// Gunakan updateOrCreate untuk menghindari duplicate key error
|
||||
StmtEntry::updateOrCreate(
|
||||
[
|
||||
'stmt_entry_id' => $entryData['stmt_entry_id']
|
||||
],
|
||||
$entryData
|
||||
);
|
||||
|
||||
// Delete existing records with these IDs to avoid conflicts
|
||||
StmtEntry::whereIn('stmt_entry_id', $entryIds)->delete();
|
||||
|
||||
// Insert all records in the chunk at once
|
||||
StmtEntry::insert($entry);
|
||||
$totalProcessed++;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset entry batch after processing
|
||||
DB::commit();
|
||||
|
||||
Log::info("Berhasil memproses {$totalProcessed} record dengan updateOrCreate");
|
||||
|
||||
// Reset entry batch after successful processing
|
||||
$this->entryBatch = [];
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
DB::rollback();
|
||||
|
||||
Log::error("Error in saveBatch: " . $e->getMessage() . "\n" . $e->getTraceAsString());
|
||||
$this->errorCount += count($this->entryBatch);
|
||||
|
||||
// Reset batch even if there's an error to prevent reprocessing the same failed records
|
||||
$this->entryBatch = [];
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user