This topic describes the object synchronization feature, which you can use to synchronize specific tables in databases that are on occasionally connected systems.
Introduction to Object Synchronization
Object synchronization is a set of tools available with InterSystems IRIS® data platform objects that allows application developers to set up a mechanism to synchronize databases on occasionally connected systems. By this process, each database updates its objects. Object synchronization offers complementary functionality to InterSystems IRIS system tools that provide high availability. Object synchronization is not designed to provide support for real-time updates; rather, it is most useful for a system that needs updates at discrete intervals.
For example, a typical object synchronization application would be in an environment where there is a master copy of a database on a central server and secondary copies on client machines. Consider the case of a sales database, where each sales representative has a copy of the database on a laptop computer. When Mary, a sales representative, is off site, she makes updates to her copy of the database. When she connects her machine to the network, the central and remote copies of the database are synchronized. This can occur hourly, daily, or at any interval.
Object synchronization between two databases involves updating each of them with data from the other. However, InterSystems IRIS does not support bidirectional synchronization as such. Rather, updates from one database are posted to the other; then updates are posted in the opposite direction. For a typical application, if there is a main database and one or more local databases (as in the previous sales database example), it is recommended that updates are from the local to the main database first, and then from the main database to the local one.
For object synchronization, the idea of client and server is by convention only. For any two databases, you can perform bidirectional updates; if there are more than two databases, you can choose what scheme you use to update all of them (such as local databases synchronizing with a main database independently).
This section addresses the following topics:
To ensure that updates work properly, each object in a database should be uniquely distinguishable. To provide this functionality, InterSystems IRIS gives each individual object instance a GUID — a globally unique ID. The GUID makes each object universally unique.
The GUID is optionally created, based on the value of the GUIDENABLED parameter. If GUIDENABLED has a value of 1, then a GUID is assigned to each new object instance.
Consider the following example. Two databases are synchronized and each has the same set of objects in it. After synchronization, each database has a new object added to it. If the two objects share a common GUID, object synchronization considers them the same object in two different states; if each has its own GUID, object synchronization considers them to be different objects.
How Updates Work
Each update from one database to another is sent as a set of transactions. This ensures that all interdependent objects are updated together. The content of each transaction depends on the contents of the journal for the source database. The update can include one or more transactions, up to all transactions that have occurred since the last synchronization.
Resolution of the following conditions is the responsibility of the application:
If two instances that share a unique key have different GUIDs. This requires determining if the two records describe a single object or two unique objects.
If two changes require reconciliation. This requires determining if the two changes were to a common property or to non-intersecting sets of properties.
The SyncSet and SyncTime Objects
When two databases are to be synchronized, each has transactions in it that the other lacks. This is illustrated in the following diagram:
Two Unsynchronized Databases
Here, database A and database B have been synchronized at transaction 536 for database A and transaction 112 for database B. The subsequent transactions for each database need to be updated from each to the other. To do this, InterSystems IRIS uses what is called a SyncSet object. This object contains a list of transactions that are used to update a database. For example, when synchronizing database B with database A, the default contents of the SyncSet object are transactions 547, 555, 562, and 569. Analogously, when synchronizing database A with database B, the default contents of the SyncSet object are transactions 117, 124, 130, and 136. (The transactions do not use a continuous set of numbers, because each transaction encapsulates multiple inserts, updates, and deletes — which themselves use the intermediate numbers.)
Each database holds a record of its synchronization history with the other. This record is called a SyncTime table. For database, its contents are of the form:
Database Namespace Last Transaction Sent Last Transaction Received
B User 536 112
The numbers associated with each transaction do not provide any form of a time stamp. Rather, they indicate the sequence of filing for transactions within an individual database.
Once database B has been synchronized with database A, the two databases might appear as follows:
Two Databases, Where One Has Been Synchronized with the Other
Because the transactions are being added to database B, they result in new transaction numbers in that database.
Analogously, the synchronization of database B with database A results in 117, 124, 130, and 136 being added to database A (and receiving new transaction numbers there):
Two Synchronized Databases
Note that the transactions from database B that have come from database A (140 through 162) are not updated back to database A. This is because the update from B to A uses a special feature that is part of the synchronization functionality. It works as follows:
Each transaction in a database is labeled with what can be called a database of origin. In this example, transaction 140 in database B would be marked as originating in database A, while its transaction 136 would be marked as originating in itself (database B).
The SyncSet.AddTransactions() method, which bundles a set of transactions for synchronization, allows you to exclude transactions that originate in a particular database. Hence, when updating from B to A, AddTransactions() excludes all transactions that originate in database A — because those have already been added to the transaction list for database B.
This functionality prevents creating infinite loops in which two databases continually update each other with the same set of transactions.