“Partial” Document Updates in Marten 7

Just continuing a loose series about recent improvements in the big Marten 7.0 release:

As part of the big Marten 7 release a couple weeks ago, core team member Babu Annamalai made a huge contribution with a brand new model for making “partial” document updates that’s backed with native PostgreSQL operations. See Babu’s post Marten native partial updates – patching for much more information and details about everything that’s supported now.

Let’s put this into perspective with a quick sample. Here’s a simplistic Wolverine handler that updates a single member on a stored document:

 public static async Task Handle(ApproveInvoice command, IDocumentSession session)
    {
        // Load the invoice
        var invoice = await session.LoadAsync<Invoice>(command.InvoiceId);
        invoice.Approved = true;
        
        // Tell Marten to persist the new version
        session.Store(invoice);
        
        // Commit the one pending change
        await session.SaveChangesAsync();
    }

In the code above, I’m loading the whole document, changing one property, and committing the changes back to the database. Under the covers we’re making two round trips to the database, deserializing the starting state of the Invoice document, then serializing the end state of the Invoice document.

With the new patching support, let’s rewrite that handler to this:

 public static async Task Handle(ApproveInvoice command, IDocumentSession session)
    {
        // Tell Marten what to change
        session.Patch<Invoice>(command.InvoiceId).Set(x => x.Approved, true);

        // Commit the one pending change
        await session.SaveChangesAsync();
    }

In that second version, we’re doing a lot less work. There’s only one database call to overwrite the Approved value within the existing Invoice document. While it’s a nontrivial operation to reach inside the JSON in the database, we’re not having to do any serialization in memory.

Marten technically had this feature set already, but our older support depended on the PLv8 extension to PostgreSQL that’s more or less deprecated now. Babu’s work for Marten 7 brings this very important feature set back into play for the majority of users who don’t want to or can’t utilize the older PLv8 backed support.

2 thoughts on ““Partial” Document Updates in Marten 7

  1. Nice, while I never had any runtime issues with PLv8 myself, earlier versions took *hours* to build, as it required building the V8 engine from scratch every time. And of course, not all cloud providers support PLv8, so this is good news.

    Is there any impact (negative/positive) on performance from switching to native patching support? I imagine it would only make a difference for patch-heavy workloads, of course.

    1. I have no idea about the performance. The killer issue was just that it was becoming much harder for folks to use PLv8 on just about any cloud offering. My understanding is that Google is mostly killing off V8. The PLV8 team is building a new JS extension to PostgreSQL. I really, really wish that would just be part of PostgreSQL core though

Leave a comment