Matt, The original design of StoreObject (which is what Bucket.store() returns) was that it would encapsulate the entire read/modify/write cycle in a very Java-y / enterprise-y way. This is why it takes a Resolver and a Mutator; it does a fetch, resolves conflicts, passes the resolved object to the Mutator, then stores the result of the mutation to Riak.
Several users put in requests to make the fetch/resolve portion of that optional as they had a workflow where that wasn't ideal and didn't wanted to store a previously fetched value without fetching it again. This is why the 'withoutFetch()' method was introduced along with the @RiakVClock annotation. When using withoutFetch() no fetch is performed, and no conflict resolution occurs. Any ConflictResolver you pass in is simply not used / ignored ... except possibly if you're using returnBody() Your code here: bucket.store(record).returnBody(true).withoutFetch().withResolver(myConflictResolver); is not doing a fetch or conflict resolution before storing your data. It's just storing `record` in Riak. If that POJO has a vclock from a previous fetch available via a @RiakVClock annotated field it will be used. Otherwise, you're doing a store without a vclock. I suspect where your confusion is stemming from is that you've also specified 'returnBody()' and you're creating a sibling in that store operation. When that's the case the "body" is going to be multiple objects (all the siblings) which require resolution as StoreObject.execute() only returns a single object back to the caller. The same Resolver used if you had done the pre-fetch is employed. If you haven't passed in a Resolver then the DefaultResolver is used which ... isn't really a "resolver" - it simply passes through an object if there's only one, or throws an exception if there's multiple (siblings) present. Thanks, - Roach On Sun, Aug 11, 2013 at 5:41 AM, Guido Medina <[email protected]> wrote: > Hi Matt, > > Like Sean said, you should have a mutator if you are dealing with conflict > resolution in domain objects; a good side effect of using a mutator is that > Riak Java client will fetch-modify-write so your conflict resolver will be > called once(?), if you don't use mutators, you get the effect you are > describing(?) or in other words, you have to treat the operations as > non-atomic and do things twice. > > There are two interfaces for mutations: Mutation and > ConditionalStoreMutation, the 2nd interface will write only if the object > was actually mutated, you must return true or false to state if it was > mutated or not, which can be helpful if you are "mutating" an object and you > discover the change you are requesting to make was already in place, then to > save I/O, siblings creation and all implied on a write operation you decide > not to write back. > > Mutation and conflict resolution are two separate concerns, but if you > specify a mutator and a conflict resolver, conflict resolution will happen > after the object is fetched and it is ready to be modified, which will > emulate an atomic operation if you use a domain object. > > If you use a raw RiakObject, you must fetch, resolve the conflicts and on > the write operation pass the VClock which is not a trivial nor easy to > understand in code. > > HTH, > > Guido. > > > > On 11/08/13 03:32, Sean Cribbs wrote: > > I'm sure Roach will correct me if I'm off-base, but I believe the store > operation does a fetch and resolve before writing. I think the ideal way to > do that is to create a Mutation<T> (T being your POJO) as well, in which > case it's less of a "store" and more of a "fetch-modify-write". The way to > skip the fetch/modify is to use the withoutFetch() option on the operation > builder. > > > On Sat, Aug 10, 2013 at 6:50 PM, Matt Painter <[email protected]> wrote: >> >> Hi, >> >> I've just rolled up my sleeves and have started to make my application >> more robust with conflict resolution. >> >> I am currently using a @RiakVClock in my POJO (I need to think more about >> whether the read/modify/write approach is preferable or whether I'd have to >> rearchitect things). >> >> I read in the Riak Handbook the recommendation that conflicts are best >> resolved on read - not write - however the example App.java snipping on the >> Storing data in Riak page in the Java client's doco uses a resolver on both >> the store() and fetch() operations. >> >> Indeed, if I don't specify my conflict resolver in my store(), things blow >> up (in my unit test, mind - I'm still getting my head around the whole area >> so my test may be a bit contrived). >> >> However when I use it in both places, my conflicts are being resolved >> twice. Is this anticipated? >> >> My store is: >> >> >> bucket.store(record).returnBody(true).withoutFetch().withResolver(myConflictResolver); >> >> and my fetch is: >> >> bucket.fetch(id, Record.class).withResolver(myConflictResolver).execute(); >> >> The order of operations in my test is: >> >> Store new record >> Fetch the record as firstRecord >> Fetch the record as secondRecord >> Modify a field on firstRecord and secondRecord >> Save firstRecord >> Save secondRecord - this invokes my resolver with two siblings >> Read record - this also invokes my resolver with the two siblings >> >> Am I missing something? Or is this what's supposed to happen? I'm not too >> worried - the double-handling is hardly that intensive - but I'm keen to get >> it right. >> >> Thanks in advance, >> Matt >> >> _______________________________________________ >> riak-users mailing list >> [email protected] >> http://lists.basho.com/mailman/listinfo/riak-users_lists.basho.com >> > > > > -- > Sean Cribbs <[email protected]> > Software Engineer > Basho Technologies, Inc. > http://basho.com/ > > > _______________________________________________ > riak-users mailing list > [email protected] > http://lists.basho.com/mailman/listinfo/riak-users_lists.basho.com > > > > _______________________________________________ > riak-users mailing list > [email protected] > http://lists.basho.com/mailman/listinfo/riak-users_lists.basho.com > _______________________________________________ riak-users mailing list [email protected] http://lists.basho.com/mailman/listinfo/riak-users_lists.basho.com
