Client Side Deltas

Data Abstract Data Tables work in disconnected mode, i.e. any updates, deletions or inserts performed on them aren't immediately reflected in the underlying database, but are instead collected in a local cache. This cached list of changes is referred to as a delta and will eventually be streamed over to the server to be applied to the physical database.

This operation is commonly handled by the remote data adapters's Update or ApplyUpdates methods, which will use a DataStreamer component to serialize and deserialize the information to a stream and send that stream across the network to the server.

It's important to note that each data table will generate a separate delta of changes, but several of these deltas can be applied to the server with a single method call.

Applying Updates

When Update or ApplyUpdates is called, the remote data adapter creates a new stream to contain the data that will be sent to the server. It will then loop through all the data tables that want to apply their updates, and use the data streamer to write the delta for all those named in the array 'aTableNameArray'.

The deltas written in the stream are conceptually similar to ADO.NET diffgrams, but they are written in a manner that is specific to the data streamer being used. For example, the Bin2DataStreamer will write deltas in an efficient binary format that is also compatible between all Data Abstract platforms and is much less verbose than the original XML diffgrams. The XmlDataStreamer (which is currently only available for Delphi) writes deltas as XML instead - a format that is more verbose than binary data, but in exchange is parseable by non-DA clients or servers. Finally the JsonDataStreamer is available for .NET, Delphi and JavaScript platforms and transmits delta updates in an easily parseable human readable JSON format.

Once all the deltas are written to the stream, the remote data adapter will use the call configured in its DataUpdateCall/UpdateDataCall property to invoke a remote method on the server and deliver the stream for updating.

Once the remote method call is completed, the remote data adapter might receive back a stream containing new deltas generated by the server. If this is the case, it will then use the data streamer again to unpack these deltas and merge any changes back into the original Data Table. This might happen if certain changes failed on the server, or if fields have been configured to automatically be refreshed from the server.

If no stream is received back, all changes are considered successfully applied, and the local delta will simply be discarded.

To understand how you can take advantage of this, you need to understand how deltas are structured and how they work, which is discussed in more detail in the Deltas and Delta Changes topics.

Updates on the Server

When the server receives changes from the client, it will unpack the received delta, again using a data streamer, start a transaction and then begin processing each deltas sequentially.

Update Rules

The sequence of updates is determined in two ways: if the service's schema has a set of Update Rules defined, it will follow the order in which these rules are ordered. This provides you with a no-code mechanism to apply updates in the specific order you decide and to restrict processing of the delta to changes of a certain type in any of those steps. If no update rules are defined, the order is determined by how the client application wrote the deltas in the incoming stream.

Business Processors

To apply the changes contained in each delta, the remote service uses the functionality of a special component called a Business Processor. Business processors can be either auto-created or manually dropped at design-time on the design surface of the component.

Each Business Processor applies to one specific data table in the service schema (identified through the ReferencedDataTable property) and will only be responsible for handling the deltas for that table.

Business Processors provide a variety of events where you can add custom business logic. For instance, the BeforeProcessDelta/OnBeforeProcessDelta event can be used to log that a certain number of updates are about to be processed or check if the current user has enough privileges to update the data table in question, while the BeforeProcessChange/OnBeforeProcessChange event could be used to inspect or adjust the individual changes.

In addition to these events, the Business Processor component includes properties that determine if the SQL for inserts, updates and deletes should be auto-generated or whether you want to use a specific command contained in the service schema. In the majority of cases, auto generated SQL will work just fine, but if you want explicit control on what SQL will be run, explicit commands defined in your schema can be specified.

Processing changes

The first thing the Business Processor does when processing changes is to create and prepare the appropriate commands that will be needed to apply INSERTs, UPDATEs and DELETEs to the database. Once the commands are ready, the business processor will then loop through all changes in the delta in the order in which they have been added and execute the respective commands.

If an update is successful, the delta change will (by default) be removed from the delta, and the next one will be processed. If the update fails, the delta change will be preserved, its Status property will be set to Failed and the exception message will be logged in the Message property of the delta change.

Another possible situation in which delta changes are kept in the delta and sent back to the client is when you set the ServerAutoRefresh property of any of the fields of the data table to true. Whenever you have ServerAutoRefresh fields, the Business Processor generates a select statement for the current row and writes the new values in the delta change and ensures it doesn't get removed from the delta. The same happens whenever AutoInc fields are present and new records are inserted.

The remote data adapter will then be able to merge these trigger-modified values once the new delta is received.

You can also decide to keep delta changes in a delta programmatically by setting the CanRemove property of the event arguments of the BeforeProcessChange/OnBeforeProcessChange or AfterProcessChange/OnAfterProcessChange events.

The server will return a new stream containing the remaining changes, if one or more changes have been kept in the delta. The client can then process them to merge updated values back into the dataset or to inform the user of failed updates.

See Also