Introduction to OCC
Optimistic Concurrency Control (OCC) is a strategy used to manage shared resources and prevent "lost updates" or race conditions when multiple users or processes attempt to modify the same resource simultaneously.
Google API resources contain an Etag property used by the server to control for optimistic concurrency. If the Etag value provided when modifying a resource does not match the current value on the server, it returns an error, usually with status Aborted (Check the documentation of the API you are using for specific OCC error codes).
OCC Steps demonstrated with IAM
Example
The following example demonstrates how to implement OCC with IAM and the Google.Cloud.PubSub.V1 library.
PublisherServiceApiClient client = PublisherServiceApiClient.Create();
try
{
// Get the current IAM Policy with the current Etag.
Policy policy = client.IAMPolicyClient.GetIamPolicy(new GetIamPolicyRequest
{
Resource = topicName,
});
// Modify the local IAM Policy object.
Binding binding = policy.Bindings.FirstOrDefault(b => b.Role == role);
if (binding is null)
{
binding = new Binding { Role = role };
policy.Bindings.Add(binding);
}
if (!binding.Members.Contains(member))
{
binding.Members.Add(member);
}
// Attempt to set the modified policy, it contains the Etag value from when it was read.
client.IAMPolicyClient.SetIamPolicy(new SetIamPolicyRequest
{
Resource = topicName,
Policy = policy
});
// The policy was modified successfully.
}
catch (RpcException ex) when ( ex.StatusCode == StatusCode.Aborted )
{
// A concurrency conflict usually manifests as Aborted but depending on the API
// other error codes may be used, like FailedPrecondition.
// To ensure the OCC mechanism is robust, check the documentation for the API
// you are implementing OCC for.
// Handle the etag mismatch. For example, retry the change or prompt the user to
// submit their changes again.
}