Patching a document in the scope of an NServiceBus message

119 views
Skip to first unread message

saguiitay

unread,
Aug 12, 2012, 9:20:09 AM8/12/12
to rav...@googlegroups.com, ar...@tzunami.com
I'm trying to call Patch (Client API) from within an NServiceBus IHandleMessages<T> handler:
DocumentStore.DatabaseCommands.Patch(
               CurrentAction.Id,
               new[]
                    {
                        new PatchRequest
                            {
                                Type = PatchCommandType.Set,
                                Name = "Progress",
                                Value = value
                            }
                    }
               );
 
Looking at the RavenDb console, I can see the request being submitted to the server:
Request #59,104: POST    -     6 ms - <default>  - 200 - /bulk_docs
        PATCH actions/449
 
However, the document is not updated in the Studio UI.
Only once the NServiceBus message finishes handling (and the RavenUnitOfWork is "closed") all the patches are reflected in the document.
 
Notes:
  • The patches are submitted via the DocumentStore, and not via the same DocumentSession used in the RavenUnitOfWork
  • DocumentStore is a singleton
 
Am I missing something here?
Is it possible that NServiceBus affects the way that RavenDb's patching mechanism work, even though I'm not using the same DocumentSession?

Kijana Woodard

unread,
Aug 12, 2012, 9:25:59 AM8/12/12
to rav...@googlegroups.com

NSB processes messages in a transaction.

saguiitay

unread,
Aug 12, 2012, 9:35:13 AM8/12/12
to rav...@googlegroups.com
Does that mean that NSB adds the Patch request to the transaction?
In that case, how come I see the request on the server side?
 
Also, according to the RavenDb documentation (http://ravendb.net/docs/client-api/partial-document-updates), Patch is not transactional:

This can save bandwidth and be faster, but it is not a transactional operation, and as such only the last patching command is actually going to be persisted.

Kijana Woodard

unread,
Aug 12, 2012, 9:50:24 AM8/12/12
to rav...@googlegroups.com

Not sure.
You would see the activity, but it still hasn't committed. If exception, it would rollback.

The behavior suggests it is getting enlisted in the ambient transaction even though it wouldn't be involved in a normal raven session transaction since, as you said, this is a call off the singleton document store.

Oren Eini (Ayende Rahien)

unread,
Aug 12, 2012, 11:01:43 AM8/12/12
to rav...@googlegroups.com
Instead of using database commands, use session Defer to make sure you ate running as part of the tx

saguiitay

unread,
Aug 12, 2012, 11:13:10 AM8/12/12
to rav...@googlegroups.com
This still doesn't work.
I've changed my code to the following:
 
var value = new RavenJValue(progress);
 
using (var session = DocumentStore.OpenSession())
{
    session.Advanced.Defer(new PatchCommandData()
        {
            Key = CurrentAction.Id,
            Patches = new[]
                {
                    
new PatchRequest
                        {
                            Type = PatchCommandType.Set,
                            Name = "Progress"
,
                            Value = value
                        }
                }
        });
 
    session.SaveChanges();
}

 

And the "Progress" property is still not updated on the Studio side (I indeed see the PATCH request being send to the server when calling SaveChanges).

Oren Eini (Ayende Rahien)

unread,
Aug 12, 2012, 11:25:21 AM8/12/12
to rav...@googlegroups.com
Do you also see the TC commit?

Kijana Woodard

unread,
Aug 12, 2012, 11:34:37 AM8/12/12
to rav...@googlegroups.com

Now it's definitely part of the transaction. You won't see it until the NSB transaction commits. This is by design for NSB so you can have multiple handlers succeed or fail together as a unit per message.

saguiitay

unread,
Aug 12, 2012, 12:11:35 PM8/12/12
to rav...@googlegroups.com
@Kijana - this doesn't make sense - I have no way of writing to the database WITHOUT taking part of the transaction?!
 
@Oren - by TC you mean the Transaction Commit? I can see it at the end of the NSB message handling.
 
I've noticed something weird - after calling patch on a *new* session using the defer method, the Studio still shows the old value.
However, if I call DocumentSession.Advanced.Refresh() on the NSB session, I'm getting the correct value.
This is extremely confusing!

Oren Eini (Ayende Rahien)

unread,
Aug 12, 2012, 12:13:25 PM8/12/12
to rav...@googlegroups.com
Please show the fiddler output

Kijana Woodard

unread,
Aug 12, 2012, 12:41:24 PM8/12/12
to rav...@googlegroups.com

Yes. You could make an explicit new transaction. You probably don't want to unless you want to ensure all that code is idempotent.

saguiitay

unread,
Aug 13, 2012, 4:21:40 AM8/13/12
to rav...@googlegroups.com
Attached is the Fiddler's output.
There are 5 requests there - the first 2 are for loading the model from the database. This is fine. The next 3 are for the patching.
 
One thing that I've noticed immediately, is that the "Raven-Transaction-Information" of all the requests is the same.
This suggest that as Kijana said, the patch is being done as part of the ambient transaction, even though I've opened a new session...
31_Full.txt

Oren Eini (Ayende Rahien)

unread,
Aug 13, 2012, 4:23:53 AM8/13/12
to rav...@googlegroups.com
Can you send this as a saz file?

saguiitay

unread,
Aug 13, 2012, 6:06:10 AM8/13/12
to rav...@googlegroups.com
Sure.
Here it is.
RavenDb.saz

Oren Eini (Ayende Rahien)

unread,
Aug 13, 2012, 6:23:20 AM8/13/12
to rav...@googlegroups.com
Okay, great.
I can see that you run the operation in the context of the transaction.
What I do NOT see is the actual transaction commit.

How are you running this?

saguiitay

unread,
Aug 13, 2012, 7:03:53 AM8/13/12
to rav...@googlegroups.com
Here's the full session, including the commit of the transaction.
RavenDb2.saz

Oren Eini (Ayende Rahien)

unread,
Aug 13, 2012, 7:08:16 AM8/13/12
to rav...@googlegroups.com
There is not PATCH here.

saguiitay

unread,
Aug 13, 2012, 7:37:03 AM8/13/12
to rav...@googlegroups.com
I apologize for this.
I must be losing my mind.
 
I've attached a new file (double checked it this time!)
RavenDb3.saz

Oren Eini (Ayende Rahien)

unread,
Aug 16, 2012, 12:11:31 PM8/16/12
to rav...@googlegroups.com
Sorry for not getting back earlier.
The code looks good, it looks like it should work.

Attached is a passing test
PatchingWithDTC.cs
Reply all
Reply to author
Forward
0 new messages