You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ignite.apache.org by Prasad Bhalerao <pr...@gmail.com> on 2018/02/12 10:57:17 UTC

Distributed transaction (Executing task on client as well as on key owner node)

Hi,

I am trying to test the distributed transaction support using following
piece of code. While debugging the code I observed that code executes on
client node first and after doing commit the code executes on a node which
owns that kay.

What I am trying to do is, to collocate the data to avoid the network call
as my data in real use case is going to big. But while debugging the code,
I observed that entry processor first executes on client node, gets all the
data executes the task. and after commit executes the same code on remote
node.

Can someone please explain this behavior? My use case to execute the task
on nodes which owns the data in single transaction.

private static void executeEntryProcessorTransaction(IgniteCache<Long,
Person> cache) {
    Person val=null;
    try (Transaction tx =
Ignition.ignite().transactions().txStart(TransactionConcurrency.OPTIMISTIC,TransactionIsolation.SERIALIZABLE))
{
  long myid =6l;
        CacheEntryProcessor entryProcessor = new MyEntryProcessor();
        cache.invoke(myid, entryProcessor);
        System.out.println("Overwrote old value: " + val);
        val = cache.get(myid);
        System.out.println("Read value: " + val);

        tx.commit();
        System.out.println("Read value after commit: " +   cache.get(myid));
    }
}



Thanks,
Prasad

Re: Distributed transaction (Executing task on client as well as on key owner node)

Posted by vkulichenko <va...@gmail.com>.
Hi Prasad,

I understand that the example you provided can be a simplified one, however
wanted to mention that this particular piece of code does not require a
transaction at all. You can just execute a single invoke() operation,
optionally returning required value (its API allows that). This will work
even with ATOMIC cache which is much faster than TRANSACTIONAL and will
properly collocate everything.

-Val



--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/

Re: Distributed transaction (Executing task on client as well as on key owner node)

Posted by dkarachentsev <dk...@gridgain.com>.
Hi Prasad,

This approach will work with multiple keys if they are collocated on the
same node and you start/stop transaction in the same thread/task. There no
other workaround.

Thanks!
-Dmitry



--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/

Re: Distributed transaction (Executing task on client as well as on key owner node)

Posted by Prasad Bhalerao <pr...@gmail.com>.
 Hi,

My use case is to collocate the data and execute the task on that node. But
I want to execute >1000 number of such tasks in collocate task mode and all
such tasks should be executed in a single transaction. If any one of the
task fails, I want to rollback the complete transaction. The reason to
execute the task collocate mode is my input data is going to be huge. Can
you please explain how to implement behavior using your solution?
As per your  solution I will be executing transaction.commit 1000 times if
I have 1000 such compute tasks but if any one of it fails I do not have a
way to rollback complete transaction.

Is there any alternative to implement this?



Thanks,
Prasad

On Mon, Feb 12, 2018 at 6:22 PM, Ilya Lantukh <il...@gridgain.com> wrote:

> Hi,
>
> The fact that code from invoke(...) is executed on node that initiated
> transaction ("near node" in ignite terminology) is a known issue. There is
> a ticket for it (https://issues.apache.org/jira/browse/IGNITE-3471), but
> it hasn't been fixed yet.
>
> To solve your initial goal, you might want to start transaction on the
> primary node for your key. It can be achieved by using
> ignite.compute().affinityRun(...), but in this case you have to start
> transaction inside affinityRun closure.
>
> Like this:
> ignite.compute().affinityRun(cacheName, key,
>             () -> {
>                 try (Transaction tx = Ignition.ignite().transactions().txStart(...))
> {
>                     cache.invoke(key, entryProcessor);
>
>                     tx.commit();
>                 }
>             }
>     );
> }
>
> In this case you will minimize overhead to modify entry in cache -
> entryProcessor will be executed only on nodes that own the key, and stored
> value shouldn't be transferred between nodes at all.
>
> Hope this helps.
>
>
>
> On Mon, Feb 12, 2018 at 1:57 PM, Prasad Bhalerao <
> prasadbhalerao1983@gmail.com> wrote:
>
>> Hi,
>>
>> I am trying to test the distributed transaction support using following
>> piece of code. While debugging the code I observed that code executes on
>> client node first and after doing commit the code executes on a node which
>> owns that kay.
>>
>> What I am trying to do is, to collocate the data to avoid the network
>> call as my data in real use case is going to big. But while debugging the
>> code, I observed that entry processor first executes on client node, gets
>> all the data executes the task. and after commit executes the same code on
>> remote node.
>>
>> Can someone please explain this behavior? My use case to execute the task
>> on nodes which owns the data in single transaction.
>>
>> private static void executeEntryProcessorTransaction(IgniteCache<Long,
>> Person> cache) {
>>     Person val=null;
>>     try (Transaction tx = Ignition.ignite().transactions
>> ().txStart(TransactionConcurrency.OPTIMISTIC,TransactionIsolation.SERIALIZABLE))
>> {
>>   long myid =6l;
>>         CacheEntryProcessor entryProcessor = new MyEntryProcessor();
>>         cache.invoke(myid, entryProcessor);
>>         System.out.println("Overwrote old value: " + val);
>>         val = cache.get(myid);
>>         System.out.println("Read value: " + val);
>>
>>         tx.commit();
>>         System.out.println("Read value after commit: " +
>> cache.get(myid));
>>     }
>> }
>>
>>
>>
>> Thanks,
>> Prasad
>>
>
>
>
> --
> Best regards,
> Ilya
>

Re: Distributed transaction (Executing task on client as well as on key owner node)

Posted by Ilya Lantukh <il...@gridgain.com>.
Hi,

The fact that code from invoke(...) is executed on node that initiated
transaction ("near node" in ignite terminology) is a known issue. There is
a ticket for it (https://issues.apache.org/jira/browse/IGNITE-3471), but it
hasn't been fixed yet.

To solve your initial goal, you might want to start transaction on the
primary node for your key. It can be achieved by using
ignite.compute().affinityRun(...), but in this case you have to start
transaction inside affinityRun closure.

Like this:
ignite.compute().affinityRun(cacheName, key,
            () -> {
                try (Transaction tx =
Ignition.ignite().transactions().txStart(...)) {
                    cache.invoke(key, entryProcessor);

                    tx.commit();
                }
            }
    );
}

In this case you will minimize overhead to modify entry in cache -
entryProcessor will be executed only on nodes that own the key, and stored
value shouldn't be transferred between nodes at all.

Hope this helps.



On Mon, Feb 12, 2018 at 1:57 PM, Prasad Bhalerao <
prasadbhalerao1983@gmail.com> wrote:

> Hi,
>
> I am trying to test the distributed transaction support using following
> piece of code. While debugging the code I observed that code executes on
> client node first and after doing commit the code executes on a node which
> owns that kay.
>
> What I am trying to do is, to collocate the data to avoid the network call
> as my data in real use case is going to big. But while debugging the code,
> I observed that entry processor first executes on client node, gets all the
> data executes the task. and after commit executes the same code on remote
> node.
>
> Can someone please explain this behavior? My use case to execute the task
> on nodes which owns the data in single transaction.
>
> private static void executeEntryProcessorTransaction(IgniteCache<Long,
> Person> cache) {
>     Person val=null;
>     try (Transaction tx = Ignition.ignite().transactions().txStart(
> TransactionConcurrency.OPTIMISTIC,TransactionIsolation.SERIALIZABLE)) {
>   long myid =6l;
>         CacheEntryProcessor entryProcessor = new MyEntryProcessor();
>         cache.invoke(myid, entryProcessor);
>         System.out.println("Overwrote old value: " + val);
>         val = cache.get(myid);
>         System.out.println("Read value: " + val);
>
>         tx.commit();
>         System.out.println("Read value after commit: " +
> cache.get(myid));
>     }
> }
>
>
>
> Thanks,
> Prasad
>



-- 
Best regards,
Ilya