SyncBatch
Overview
SyncBatchTask synchronizes data from batch processing tables to their corresponding production tables. It performs a delete-and-insert operation to replace existing records in production tables with the updated records from batch tables, ensuring that batch-processed data (visits, quotes, custom properties, GFE compliance, and change events) is promoted to production.
Use this task when: You need to commit batch-processed data from staging/batch tables to production tables after completing batch calculations or updates.
Don't use this task when: You need to process individual records incrementally (use direct repository save methods), need to preserve historical production data without replacement, or when batch tables haven't been populated yet.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
SyncQuote |
bool |
No | true |
Synchronizes Quote records from QuoteBatch to Quote table and syncs auto-benefits status maps |
SyncVisit |
bool |
No | true |
Synchronizes Visit records from VisitBatch to Visit table and syncs auto-benefits status maps |
SyncCustomPropertyMap |
bool |
No | true |
Synchronizes custom property mappings from CustomPropertyMapBatch to CustomPropertyMap table |
SyncVisitGFECompliance |
bool |
No | true |
Synchronizes GFE compliance records from VisitGFEComplianceBatch to VisitGFECompliance (only for GFE-enabled customers) |
SyncRemovedCustomPropertyMaps |
bool |
No | true |
Removes custom property maps from production that are missing in batch (cleanup operation) |
SyncVisitChangeEvent |
bool |
No | true |
Synchronizes visit change events from VisitChangeEventBatch to VisitChangeEvent table |
Execution Flow
Processing Algorithm
The task executes a two-phase synchronization algorithm for each entity type:
Phase 1: Delete Matching Records
Delete all records from the production table where the join key matches a record in the batch table.
Phase 2: Insert Batch Records
Insert all records from the batch table into the production table.
Both operations are wrapped in a database transaction to ensure data consistency.
Example Execution
For Visit synchronization:
- Delete all Visit records where Visit.Key matches any VisitBatch.Key
- Insert all records from VisitBatch into Visit
- Update AutoApplyBenefitsStatusMap for synced visits
If VisitBatch contains 100 visits and Visit contains 500 visits:
- Only the 100 matching visits (by Key) are deleted from Visit
- All 100 visits from VisitBatch are inserted
- Final Visit table contains: 400 original + 100 synced = 500 visits
Usage Examples
Example 1: Full sync after batch processing
var task = new SyncBatchTask
{
SyncQuote = true,
SyncVisit = true,
SyncCustomPropertyMap = true,
SyncVisitGFECompliance = true,
SyncRemovedCustomPropertyMaps = true,
SyncVisitChangeEvent = true
};
// All batch tables will be synced to production
Example 2: Sync only visits and quotes
var task = new SyncBatchTask
{
SyncQuote = true,
SyncVisit = true,
SyncCustomPropertyMap = false,
SyncVisitGFECompliance = false,
SyncRemovedCustomPropertyMaps = false,
SyncVisitChangeEvent = false
};
// Only Quote and Visit batch tables synced, custom properties remain unchanged
Example 3: Sync custom properties only
var task = new SyncBatchTask
{
SyncQuote = false,
SyncVisit = false,
SyncCustomPropertyMap = true,
SyncVisitGFECompliance = false,
SyncRemovedCustomPropertyMaps = true, // Also cleanup removed properties
SyncVisitChangeEvent = false
};
// Only custom property batch data is synced and cleaned up
Example 4: Part of a batch processing pipeline
// Step 1: Load visits into batch table
var loadTask = new LoadVisitsTask { /* config */ };
loadTask.Execute(dataStore);
// Step 2: Process visits in batch
var processTask = new ProcessVisitsTask { /* config */ };
processTask.Execute(dataStore);
// Step 3: Sync batch results to production
var syncTask = new SyncBatchTask(); // All defaults = true
syncTask.Execute(dataStore);
Related Tasks Comparison
| Task | Use Case | Scope | Data Flow | Transaction Safety |
|---|---|---|---|---|
| SyncBatch | Promote batch data to production | Multiple entity types | Batch tables → Production tables | Transactional per entity |
LoadVisits |
Load visits into batch table | Visits only | SQL query → VisitBatch | Bulk insert |
AutoApplyBundlesToVisitBatch |
Apply bundles to batch visits | Visits in batch | VisitBatch → QuoteBatch | Batch processing |
AutoSendLetters |
Send letters from batch visits | Letters for batch visits | VisitBatch → Email/SMS | Batch processing |
Performance Considerations
Database Impact
- Tables Read: QuoteBatch, VisitBatch, CustomPropertyMapBatch, VisitGFEComplianceBatch, VisitChangeEventBatch
- Tables Written: Quote, Visit, CustomPropertyMap, VisitGFECompliance, VisitChangeEvent, AutoApplyBenefitsStatusMap
- Operation Type: DELETE followed by INSERT for each entity type (transactional)
- Indexes Used: Primary key and join column indexes for efficient deletes
- Transaction Scope: Each entity sync operation runs in its own transaction
Optimization Tips
| Scenario | Recommendation | Rationale |
|---|---|---|
| Large batch sizes | Sync during off-peak hours | DELETE and INSERT operations can lock tables temporarily |
| Selective sync | Disable unused entity syncs | Reduces database load and execution time |
| GFE not used | Leave SyncVisitGFECompliance enabled | Task checks GFEEnabled flag and skips automatically |
| After import errors | Validate batch data before sync | Production data is replaced; errors propagate to production |
Bulk Operations
The task uses standard SQL DELETE and INSERT statements without explicit bulk copy operations. For large batch sizes (>10,000 records), consider:
- Running during maintenance windows
- Monitoring transaction log growth
- Ensuring adequate tempdb space
Error Handling
The task uses transactional SQL statements wrapped by SqlGenerator.MakeTransactionFromQuery() to ensure atomicity.
// Each sync operation is wrapped in a transaction
BEGIN TRANSACTION
DELETE [Entity] FROM [Entity] INNER JOIN [EntityBatch] ON ...
INSERT INTO [Entity] SELECT * FROM [EntityBatch]
COMMIT TRANSACTION
Important:
- Each entity sync operation is independent and runs in its own transaction
- If one entity sync fails, others may still succeed
- No rollback mechanism across different entity types
- Database constraints (foreign keys, unique indexes) are enforced during sync
- Failed transactions log errors but do not stop subsequent entity syncs
Common Pitfalls
| Issue | Problem | Solution |
|---|---|---|
| Empty batch tables | Syncing with empty batch tables deletes matching production records without replacement | Always verify batch tables contain expected data before syncing |
| Foreign key violations | Quote sync fails if VisitKey references non-existent Visit | Sync Visits before Quotes, or ensure referenced entities exist |
| Missing GFE compliance | GFE sync skipped silently if customer not GFE-enabled | Verify Customer.GFEEnabled flag matches expectations |
| Partial data loss | Only syncing some entities leaves inconsistent state | Sync all related entities together (Visit + Quote + CustomPropertyMap) |
| AutoBenefits status maps | Status maps not synced if only custom properties are updated | Enable SyncQuote or SyncVisit to sync corresponding status maps |
| Removed properties not cleaned | Custom properties persist in production after batch removal | Enable SyncRemovedCustomPropertyMaps to clean up deleted properties |
Code References
- Task Definition:
MDClarityCore/Backend/Scheduling/SyncBatchTask.cs:11 - Task Constructor:
MDClarityCore/Backend/Scheduling/SyncBatchTask.cs:20 - Execute Method:
MDClarityCore/Backend/Scheduling/SyncBatchTask.cs:31 - Field Definitions:
MDClarityCore/Backend/Scheduling/SyncBatchTask.cs:71 - SyncEntityExecutor:
MDClarityCore/Backend/Scheduling/SyncEntityExecutor.cs:10 - SyncEntity Method:
MDClarityCore/Backend/Scheduling/SyncEntityExecutor.cs:30 - GetEntitySyncSql Method:
MDClarityCore/Backend/Scheduling/SyncEntityExecutor.cs:37 - SyncCustomPropertyExecutor:
MDClarityCore/Backend/Scheduling/SyncCustomPropertyExecutor.cs:14 - SyncCustomPropertyMap Method:
MDClarityCore/Backend/Scheduling/SyncCustomPropertyExecutor.cs:28 - RemoveCustomPropertyMaps Method:
MDClarityCore/Backend/Scheduling/SyncCustomPropertyExecutor.cs:38 - AutoApplyBenefitsStatusController:
MDClarityCore/Backend/Eligibility/Implementations/AutoApplyBenefitsStatusController.cs:15 - SyncBatchAutoBenefitsStatus Method:
MDClarityCore/Backend/Eligibility/Interfaces/IAutoApplyBenefitsStatusController.cs:21 - Integration Tests:
MDClarityCore/MDClarityTest/Tests/IntegrationTests/Backend/Tasks/SyncBatchIntegrationTests.cs:22 - Quote Sync Test:
MDClarityCore/MDClarityTest/Tests/IntegrationTests/Backend/Tasks/SyncBatchIntegrationTests.cs:67 - Visit Sync Test:
MDClarityCore/MDClarityTest/Tests/IntegrationTests/Backend/Tasks/SyncBatchIntegrationTests.cs:108 - Unit Tests:
MDClarityCore/MDClarityTest/Tests/UnitTests/Backend/Scheduling/SyncBatchExecutorTests.cs:13