Course contentsShow
← C#
Lesson 1478 of 1,90813. Real-time Communication with SignalRFree lesson

Real-Time Collaborative Editing Systems

Implement optimistic locking and conflict resolution for shared document editing scenarios.

In this lesson, you will learn how to maintain data integrity in multi-user environments by implementing optimistic locking and conflict resolution for shared document editing.

When multiple users edit a document simultaneously via SignalR, the greatest challenge is ensuring that updates don't overwrite each other in a way that destroys data. Instead of locking the document and preventing others from working (pessimistic locking), we use optimistic locking.

The Concept

Every document version in your database or state store includes a Version number. When a client sends an update, they must include the version number they are basing their change on. If the current server version matches the client's version, the update is accepted and the version increments. If the version has already changed, a conflict has occurred, and the server rejects the request.

Implementation Pattern

Here is how you might structure this logic within a SignalR Hub method:

public async Task UpdateDocument(int documentId, string newContent, int clientVersion)
{
    var document = await _repository.GetByIdAsync(documentId);

    if (document.Version != clientVersion)
    {
        // Conflict detected! Notify the client to re-sync
        await Clients.Caller.SendAsync("ConflictDetected", document.Content, document.Version);
        return;
    }

    // Apply change and increment
    document.Content = newContent;
    document.Version++;
    await _repository.UpdateAsync(document);
    
    // Broadcast success
    await Clients.Others.SendAsync("DocumentUpdated", newContent, document.Version);
}

Conflict Resolution

When a conflict occurs, the client must handle the ConflictDetected signal. The strategy here is usually "Rebase and Retry." The client updates its local state with the server's current version (which it just received in the signal) and then reapplies its local changes on top of that new state. In complex scenarios, you might implement a "three-way merge" or a Operational Transformation (OT) algorithm to resolve differences at the character level, but for standard document editing, the version-check pattern ensures you never lose a user’s atomic input.

Key Takeaway: Optimistic locking preserves document integrity by using version tracking to detect collisions, requiring clients to reconcile state whenever their local version becomes stale.