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

Reply via email to