Introduction to Version Management
Geodatabase versioning capabilities are provided by the VersionManagementService. Geodatabase versioning allows users to work with the same data at the same time, giving each user an isolated view of the data. Versioning facilitates long transactions by allowing editors to work isolated within their own version of the geodatabase and across multiple edit sessions. Once an editor finishes a collection of edits, they can merge their changes back to the parent version from which their version was created. Versioning also provides save and revert capabilities as well as undo/redo. More information about versioning concepts can be found in the ArcGIS Pro documentation.
The VersionManagementService class provides tools for creating, editing, and reconciling versions, as well as undoing and redoing edits, reconciling conflicts, and applying changes to the default version. The Version Management Component provides user interface capabilities for some common versioning workflows.
Listing Available Versions
The first step to working with versions is to identify a version to work with. The version management service provides a way to list available versions using getVersionInfos.
The method expects owner
and include
parameters. This method queries a version based on owner name.
The following code example demonstrates how to get a list of versions owned by publisher1
using get
.
// Will get versions owned by publisher1.
const versionInfos = await versionManagementService.getVersionInfos({
ownerFilter: "publisher1",
includeHidden: true
});
To get all available versions, call the getVersionInfos method without passing parameters. The following code example demonstrates how to get information about all versions accessible by the current user.
const versions = await versionManagementService.getVersionInfos(); // Will list all available versions in service.
Calling getVersionInfos will only return basic information on each version. In order to get extended information about a version,
such as current server locks or conflicts, use the getVersionInfosExtended method.
The following code example demonstrates how to get information on a version using get
.
versionIdentifier = {
guid: "{422D1B63-D795-4478-A4B1-AD6109377075}",
name: "versionOwner.versionName"
}
const versionInfoExtended = await versionManagementService.getVersionInfoExtended(versionIdentifier);
These methods return versionInfoExtended and a versionInfo object. The version
object contains basic information about a version and the versionInfoExtended contains more detailed information about a version.
Find the default version information by using the defaultVersionIdentifier property on the Version
class.
The following code examples demonstrate how to get the default
.
const defaultVersionIdentifier = versionManagementService.defaultVersionIdentifier;
Changing Versions on a FeatureLayer or UtilityNetwork
The changeVersionWithResult method is used to change a layer or network's version or moment. This method changes the data source to point to a named version or historical moment. If a version has a read or write lock, then the user is unable to change versions.
Change Version iterates through the layer array, changing each layer that references the from
to reference the to
. If the web map contains utility networks, these are also changed appropriately. The method also takes from
and to
parameters to indicate the intended version to change and the intended target. These parameters accept either a Version
or a Date
(to indicate a historic moment on default).
If the target version has a local lock, then the user must first clear the lock by calling stopEditingWithResult or stopReadingWithResult, as appropriate. The getLockType method can be used to confirm if a version has a local read or edit lock.
The following code example demonstrates how to change the version of two Feature
objects.
const layer0 = new FeatureLayer({url: `https://sampleserver6.arcgisonline.com/arcgis/rest/services/Wildfire/FeatureServer/0`});
const layer1 = new FeatureLayer({url: `https://sampleserver6.arcgisonline.com/arcgis/rest/services/Wildfire/FeatureServer/1`});
const layers = [layer0, layer1];
await versionManagementService.changeVersionWithResult(
layers, // a webmap can also be passed here or a UtilityNetwork
{ name: layer0.gdbVersion, guid: "{BD3F4817-9A00-41AC-B0CC-58F78DBAE0A1}"}, // pass current layer gdbVersion and current guid of version
{ name: version.name, guid: version.guid } // pass an incoming version name and incoming version guid.
);
Creating and Deleting Versions
The createVersion method is used to create a named version. The method expects a version
, description
, and access
. The access parameter can be either private
, protected
, hidden
, or public
.
The following is a code example on how to create a new version using this method.
await versionManagementService.createVersion({
versionName: "versionOwner.versionName",
description: "my New Version",
access: "public"
});
The deleteVersion method is used to delete a named version that is no longer needed. This is typically done after a user has finished editing and has posted their changes to the default version. The method expects a versionIdentifier, which is an object that contains a version name and guid. The following code example demonstrates how to delete an existing version.
await versionManagementService.deleteVersion({
name: "versionOwner.versionName",
guid: "{BD3F4817-9A00-41AC-B0CC-58F78DBAE0A1}"
});
Altering a Version
The alterVersion method allows users to change a version's name, description, and access permissions. This method can be used to pass ownership of a version to another user. Changing access permissions can be used to make a version private
or protected
thus, restricting access. It can also be used to make a version public
, thereby granting access to other users.
The following code sample demonstrates altering a version.
await versionManagementService.alterVersion({
name: "versionOwner.versionName", // current version name
guid: "{49C6AC87-CDA8-46D4-A79B-449105981209}"}, // versionIdentifier
{
versionName: "newVersionName", // parameter to alter version name
ownerName: "newOwner",
description: "newDescription",
access: "public"
}
);
Editing Versions
Editing Versions Without an Edit Session
Users are able to edit a version without an edit session, but doing so has implications. Edits are immediately committed to the database, without the ability to undo/redo edits or revert changes. Read consistency is not guaranteed- every query to the server could return different results. This is typical website behavior. This type of editing is performed by calling applyEdits without calling start editing first.
Editing Versions with Save and Revert
Editing while in session makes use of shared and exclusive locks. The startReadingWithResult method creates a read lock (guaranteeing read-consistency) and startEditingWithResult creates a write lock. These locks should be released with matching calls to stopReadingWithResult and stopEditingWithResult respectively.
While a shared lock is held no other user can acquire an exclusive lock, and in reverse an exclusive lock will block a shared lock. Simply put readers block writers and writers block readers.
Edits are saved or reverted during the call to stopEditing. This feature is important because it allows users to easily discard their edits if they change their mind and decide not to keep the changes. By calling the stopEditing method with the option of not saving edits, users can conveniently revert back to the original version without permanently altering the content. The methods to begin sessions and end sessions require a versionIdentifier parameter to specify the version on which the edit session will be initiated or ended.
await versionManagementService.startReadingWithResult(version);
await versionManagementService.startEditingWithResult(version);
featureService.applyEdits(...); // now perform an applyEdits call
await versionManagementService.stopEditingWithResult(version, true); // if false edits will be discarded
await versionManagementService.stopReadingWithResult(version); // all locks will be cleared
Editing Versions with Undo and Redo
The undo and redo functionality allows users to easily revert or redo changes made. With the undo option, users can step back through their editing history and revert changes to a previous state, effectively undoing any modifications made. Conversely, the redo option allows users to reapply changes that were previously undone. This functionality provides flexibility and confidence to users, ensuring that they can easily correct errors or explore different design options without the fear of losing progress. An edit operation stack holds the edit moments for each operation. Undo moves backward through the stack. Redo moves forward through the stack.
await versionManagementService.startReading(version);
await versionManagementService.startEditing(version);
featureService.applyEdits(...); // now perform an applyEdits call
await versionManagementService.undo(version); // undos edits
await versionManagementService.redo(version); // redos edits
Reconcile and Post
The reconcile method compares the edit version (E.g. the named version) and the target version (default version) to find conflicts between the two. The reconcile method requires that you are the only user currently editing the version and remain so throughout the reconcile process until you save or post your edits. You must have full permissions to all the feature classes that have been modified in the version being edited. This method detects differences between features edited in the named version and features edited in the default version that have been editing since the last reconcile (i.e., different edits are made to the same feature in the named version and default). These are called conflicts. This updates the version with edits that have been made to default since the last reconcile (or version creation).
The following code sample demonstrates how to perform a reconcile on a version.
const reconcileResult = await versionManagementService.reconcile(
versionIdentifier,
{
abortIfConflicts: true,
conflictDetection: "by-object",
withPost: false
}
);
The post method is used to apply edits made on a named version to the default version. It can be called after reconciling and resolving conflicts. A reconcile operation must be performed prior to post. By posting edits, the changes made in the version are permanently applied to the default version, ensuring data consistency and synchronization across the geodatabase. The following code sample demonstrates how to perform a post operation on a version.
const postResult = await versionManagementService.post(versionIdentifier);
Conclusion
The Version
class is a powerful tool for managing feature services that work with named versioned datasets.
It provides a range of functionality to create, delete, alter, and change versions, as well as start/stop reading and editing, reconciling, posting, and getting version information. The Version
provides a comprehensive set of methods to manage versions and streamline versioning workflows.