[infinispan-dev] Atomic operations and transactions

Dan Berindei dan.berindei at gmail.com
Tue Jul 5 07:24:56 EDT 2011


On Tue, Jul 5, 2011 at 1:39 PM, Sanne Grinovero <sanne at infinispan.org> wrote:
> 2011/7/5 Dan Berindei <dan.berindei at 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
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
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)
d. Pessimistic locking: if the key is modified between 2) and 5), the
entire transaction has to be redone
e. Pessimistic locking + fresh read: no redo, but decreased throughput
because we hold the lock between 3) and 5)

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


More information about the infinispan-dev mailing list