Data changes: Row change (UPDATE)

To manage data row modifications, use dbsync_app.register_local_update() for complete row changes or dbsync_app.register_local_change() for field-specific updates to minimize conflicts. Compact the changes log with dbsync_app.compact_local_changes() to optimize synchronization and resolve potential conflicts.

Fill row modification

After doing the local UPDATE, register the change in the local sync log with the dbsync_app.register_local_update() function:
BEGIN WORK
TRY
    UPDATE customer SET ... WHERE customer_id = r_customer.customer_id
    LET s = dbsync_app.register_local_update( "customer",
                                              r_customer.customer_id )
    IF s < 0 THEN
        ERROR "Failed to register customer row modification"
        ROLLBACK WORK
        NEXT FIELD CURRENT
    END IF
CATCH
     ERROR "Failed to update the customer row"
     ROLLBACK WORK
     NEXT FIELD CURRENT
END TRY
COMMIT WORK

This will register a change for the complete data row and all fields will be considered as modified, leading to higher concurrent data access conflicts. If you want to reduce the conflicts and allow concurrent changes on different fields on the same row, use field-wise change with dbsync_app.register_local_change().

Field-wise row modification

If only a limited number of fields need to changed, use the field-wise change function, and register the change with the dbsync_app.register_local_change() function to specify the list of fields that have been changed:
  UPDATE customer SET cust_name = r_customer.cust_name,
                      cust_city = r_customer.cust_city,
                      cust_addr = r_customer.cust_addr
                WHERE customer_id = r_customer.customer_id
  VAR colnames DYNAMIC ARRAY OF STRING
               = ["cust_name","cust_city","cust_addr"]
  LET s = dbsync_app.register_local_change( "customer", colnames,
                                            r_customer.customer_id )
  IF s < 0 THEN ROLLBACK WORK; ...  END IF
A field-wise change registration can be dynamic, by providing the list of fields which have changed since the last synchronization.
Tip:
When using dbsync_app.register_local_change(), consider to group fields that are related, even if some of these fields did not change. For example, first name and last name fields should always be specified if one of the fields is modified. Otherwise, the first name and last name could be changed individually without conflict by different end users:
  1. Client C1 changes first name of Mike Torm to Ted => Ted Torm => sync
  2. Client C2 changes last name of Mike Torm to Tiger => Mike Tiger => sync
  3. Resulting first name / last name: Ted Tiger

Compacting registered field-wise changes

If needed, it is possible to compact the changes log with the dbsync_app.compact_local_changes() function:
  LET s = dbsync_app.compact_local_changes("customer")

This will compact successive changes recorded in the local sync log, to optimize the synchronization process, and solve potential conflicts.

For example:
  1. Client C1 creates a new row in a customer table with name: BIRDY
  2. Client C1 does a sync => OK
  3. Client C2 creates a new customer row with the same name: BIRDY
  4. Client C2 does a sync => fails because of unique constraint conflict.
  5. Client C2 modifies the name BIRDY to CARLTON => local sync log contains:
    1. INSERT of customer row with name BIRDY
    2. UPDATE of customer row with name CARLTON
  6. Client C2 does a sync => still fails because of the INSERT with name BIRDY.
  7. Client C2 does compact changes log => local sync log contains now:
    1. INSERT of customer row with name CARLTON
  8. Client C2 does a sync => OK

The changes log compacting operation is left in the hands of the programmer, as application business rules may require to keep changes in detailed order.