2011/7/5 Dan Berindei <dan.berindei(a)gmail.com>:
On Tue, Jul 5, 2011 at 1:39 PM, Sanne Grinovero
<sanne(a)infinispan.org> wrote:
> 2011/7/5 Dan Berindei <dan.berindei(a)gmail.com>:
>> Here is a contrived example:
>>
>> 1. Start tx Tx1
>> 2. cache.get("k") -> "v0"
>> 3. cache.replace("k", "v0", "v1")
>> 4. gache.get("k") -> ??
>>
>> With repeatable read and suspend/resume around atomic operations, I
>> believe operation 4 would return "v0", and that would be very
>> surprising for a new user.
>> So I'd rather require explicit suspend/resume calls to make sure
>> anyone who uses atomic operations in a transaction understands what
>> results he's going to get.
>
> The problem is that as a use case it makes no sense to use an atomic
> operation without evaluating the return value.
> so 3) should actually read like
>
> 3. boolean done = cache.replace("k", "v0", "v1")
> and based on this value, the application would branch in some way, and
> so acquiring locks and waiting for each other is not enough, we can
> only support this if write skew checks are enabled, and mandate the
> full operation to rollback in the end. That might be one option, but I
> really don't like to make it likely to rollback transactions, I'd
> prefer to have an alternative like a new flag which enforces a "fresh
> read" skipping the repeatable read guarantees. Of course this wouldn't
> work if we're not actually sending the operations to the key owners,
> so suspending the transaction is a much nicer approach from the user
> perspective. Though I agree this behaviour should be selectable.
>
Ok, I'm slowly remembering your arguments... do you think the "fresh
read" flag should be available for all operations, or does it make
sense to make it an internal flag that only the atomic operations will
use?
To summarize, with this example:
1. Start tx
2. cache.get("k") -> "v0"
3. cache.replace("k", "v0", "v1")
4. gache.get("k") -> ??
5. Commit tx
The options we could support are:
a. Tx suspend: no retries, but also no rollback for replace() and 4)
will not see the updated value
might work, but looks like a crazy user experience.
b. Optimistic locking + write skew check: if the key is modified by
another tx between 2) and 5), the entire transaction has to be redone
might work as well, since people opted in for "optimistic" they should
be prepared to experience failures.
I'm not sure what the "+" stands for, how can you have optimistic
locking without write skew checks?
c. Optimistic locking + write skew check + fresh read: we only have
to
redo the tx if the key is modified by another tx between 3) and 5)
in this case we're breaking the repeatable read guarantees, so we
should clarify this very well.
d. Pessimistic locking: if the key is modified between 2) and 5),
the
entire transaction has to be redone
I don't understand what's pessimistic about this? To be pessimistic it
would attempt to guarantee success by locking at 2): during the get
operation, before returning the value.
Also "if they key is modified" implies write skew checks, so how would
this be different than previous proposals?
Generally as a user if I'm opting in for a pessimistic lock the only
exception I'm prepared to handle is a timeout, definitely not a "try
again, the values changed".
e. Pessimistic locking + fresh read: no redo, but decreased
throughput
because we hold the lock between 3) and 5)
I assume you really mean to do explicit pessimistic locking:
1. Start tx
2. cache.lock("k");
3. cache.get("k") -> "v0"
4. cache.replace("k", "v0", "v1") /// -> throw an
exception if we're
not owning the lock
5. gache.get("k") -> ??
6. Commit tx
I guess there is no reason to support option d), as we're making
an
RPC to the owner in order to get the lock anyway. I think I'm leaning
towards supporting only a) and e), but there might be cases where b)
and c) would perform better.
Dan
_______________________________________________
infinispan-dev mailing list
infinispan-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/infinispan-dev