Skip to main content

Command Palette

Search for a command to run...

Dual-Write Database System: Implementation Guide

Published
•4 min read•View as Markdown
Dual-Write Database System: Implementation Guide

Overview

The dual-write system enables simultaneous data synchronization between your Core database and Portal database. This setup ensures data consistency across both systems while maintaining separation of concerns.

System Architecture

Core Components:

  • Core Database: Primary application database

  • Portal Database: Secondary database for portal-specific functionality

  • Synchronization Service: Handles real-time data replication

  • Queue System: Manages synchronization jobs

Prerequisites

Before implementation, ensure:

  1. All migration files are executed (php artisan migrate)

  2. Configuration files are properly set up:

    • config/sync.php

    • config/sync_mapping.php

    • config/queue.php

  3. Composer dependencies are installed (composer install)

Implementation Steps

1. Model Setup

For models that require dual-write:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Traits\SyncsToPortal;

class YourModel extends Model
{
    use SyncsToPortal;

    protected $portalTable = 'portal_table_name';
    protected $syncAttributes = ['column1', 'column2', 'column3'];
    protected $portalKey = 'portal_id';

    // Optional: Define transformation logic
    public function toPortalArray()
    {
        return [
            'portal_column' => $this->core_attribute,
            'transformed_data' => $this->transformMethod(),
        ];
    }
}

2. Configuration Mapping

Update config/sync_mapping.php:

return [
    'core_table_name' => [
        'portal_table' => 'portal_table_name',
        'columns' => [
            'core_column' => 'portal_column',
            'core_foreign_key' => 'portal_foreign_key',
        ],
        'conditions' => [
            'should_sync' => true,
            'where' => ['status' => 'active'],
        ],
        'transformations' => [
            'core_field' => 'transformation_method',
        ],
    ],
    // Add more table mappings as needed
];

3. Observer Registration

Register observers in AppServiceProvider.php:

public function boot()
{
    YourModel::observe(YourModelObserver::class);
    // Register other model observers
}

Frequently Used Commands

Initial Setup Commands

# Setup portal schema structure
php artisan portal:setup

# Perform initial data synchronization
php artisan sync:initial

# Verify schema compatibility
php artisan schema:verify

Regular Operation Commands

# Monitor synchronization status
php artisan sync:monitor

# Manual schema synchronization
php artisan schema:sync

# Debug portal schema issues
php artisan portal:debug

# Test mapping configuration
php artisan sync:test-mapping

Maintenance Commands

# Compare schemas between core and portal
php artisan schema:compare

# Retry failed synchronization jobs
php artisan queue:retry sync

# View synchronization queue status
php artisan queue:listen --queue=sync

Key Configuration Files

config/sync.php

return [
    'enabled' => env('SYNC_ENABLED', true),
    'connection' => 'portal',
    'queue' => 'sync',
    'chunk_size' => 1000,
    'timeout' => 3600,
    'retry_attempts' => 3,
    'models' => [
        App\Models\User::class,
        App\Models\JobApplication::class,
        // Add other sync-enabled models
    ],
];

config/queue.php (Relevant Section)

'connections' => [
    'sync' => [
        'driver' => 'database',
        'table' => 'jobs',
        'queue' => 'sync',
        'retry_after' => 3600,
    ],
],

Implementation Best Practices

1. Data Transformation

protected function transformForPortal(array $coreData): array
{
    return [
        'portal_ready_data' => $this->transformData($coreData),
        'sync_timestamp' => now(),
        'metadata' => $this->extractMetadata(),
    ];
}

2. Error Handling

try {
    $this->synchronizer->sync($model);
} catch (SyncException $e) {
    Log::error('Sync failed: ' . $e->getMessage());
    $this->retrySync($model, $e);
}

3. Conflict Resolution

protected function resolveConflict($coreData, $portalData)
{
    // Implement your conflict resolution strategy
    return $this->useLatestTimestamp($coreData, $portalData);
}

Monitoring and Logging

Enable Detailed Logging

// In config/logging.php
'channels' => [
    'sync' => [
        'driver' => 'daily',
        'path' => storage_path('logs/sync.log'),
        'level' => 'debug',
    ],
],

Custom Monitoring

// Add to your application's monitoring system
SyncMonitor::trackPerformance();
SyncMonitor::alertOnFailureRate(0.1); // Alert if >10% failure rate

Troubleshooting Common Issues

1. Schema Mismatch

php artisan schema:verify
php artisan schema:sync --fix

2. Queue Backlog

php artisan queue:work --queue=sync --timeout=3600
php artisan queue:retry all

3. Data Inconsistency

php artisan sync:validate
php artisan sync:repair {table_name}

Performance Considerations

Batch Processing

// For large datasets
DatabaseSynchronizer::chunk(1000, function ($records) {
    $this->syncBatch($records);
});

Index Optimization

-- Portal database indexes
CREATE INDEX idx_sync_status ON portal_table (sync_status);
CREATE INDEX idx_last_sync ON portal_table (last_synced_at);

Testing Your Implementation

Unit Tests

public function test_dual_write_operation()
{
    $model = YourModel::create($testData);
    $this->assertPortalRecordExists($model->portal_id);
    $this->assertDataConsistent($model);
}

Integration Tests

public function test_synchronization_flow()
{
    $this->artisan('sync:initial')
         ->expectsOutput('Synchronization completed successfully');

    $this->assertDatabaseHas('portal_table', ['synced' => true]);
}

Rollback Procedure

Emergency Disable

// In config/sync.php
'enabled' => false,

Data Recovery

php artisan sync:rollback {timestamp}
php artisan sync:restore {backup_id}

Important Notes

  1. Always test synchronization in staging before production

  2. Monitor queue health regularly using php artisan sync:monitor

  3. Keep schema mappings updated when modifying database structure

  4. Implement proper error handling for network issues between databases

  5. Regularly validate data consistency between core and portal

This dual-write system provides robust data synchronization while maintaining system separation. Follow this guide carefully and refer to specific command help (php artisan help {command}) for detailed usage information.