When to use Ignite.Net Tansactions ?

classic Classic list List threaded Threaded
4 messages Options
Mahesh Talreja Mahesh Talreja
Reply | Threaded
Open this post in threaded view
|

When to use Ignite.Net Tansactions ?

Hi Team,
            I am working on Dot Net project and trying to implement Ignite.Net.
Being new to the world of ignite, and after having a read above transactions on ( https://apacheignite-net.readme.io/docs/transactions#atomicity-mode )
 I am a bit confused with ignite transaction atomicity-mode's. 

To give you a bit of background, I am working on a project which is being developed on microservice design/architecture, having plans to be hosted using docker containers. So to summarise, I am expecting to have a multiprocess/ multithreaded environment, wherein there can be multiple instances of a microservice and each instance of a microservice will go ahead a create an Ignite Node (Client Mode) and get connected to a cluster of server nodes.

I am dealing with simple curd operations. Each user action resulting in only a single curd operation at a time (Get/Put/Remove/Replace).  

So should I go ahead and use transactions (Pessimistic - Repeatable Read) even when I have single operations in each transaction as it locks the respective keys and provides sequential execution and is fully ACID compliant in case of multiple processes,

 Or should I just go ahead with the Atomic mode which provides atomicity and consistency but I am not sure about locks and sequential execution in case of multiple processes?
 
Jörn Franke Jörn Franke
Reply | Threaded
Open this post in threaded view
|

Re: When to use Ignite.Net Tansactions ?

Maybe you can elaborate more on your use case, because usually it is not a technical decision , but driven by user requirements.

On 9. Jul 2018, at 10:01, Mahesh Talreja <[hidden email]> wrote:

Hi Team,
            I am working on Dot Net project and trying to implement Ignite.Net.
Being new to the world of ignite, and after having a read above transactions on ( https://apacheignite-net.readme.io/docs/transactions#atomicity-mode )
 I am a bit confused with ignite transaction atomicity-mode's. 

To give you a bit of background, I am working on a project which is being developed on microservice design/architecture, having plans to be hosted using docker containers. So to summarise, I am expecting to have a multiprocess/ multithreaded environment, wherein there can be multiple instances of a microservice and each instance of a microservice will go ahead a create an Ignite Node (Client Mode) and get connected to a cluster of server nodes.

I am dealing with simple curd operations. Each user action resulting in only a single curd operation at a time (Get/Put/Remove/Replace).  

So should I go ahead and use transactions (Pessimistic - Repeatable Read) even when I have single operations in each transaction as it locks the respective keys and provides sequential execution and is fully ACID compliant in case of multiple processes,

 Or should I just go ahead with the Atomic mode which provides atomicity and consistency but I am not sure about locks and sequential execution in case of multiple processes?
 
Mahesh Talreja Mahesh Talreja
Reply | Threaded
Open this post in threaded view
|

Re: When to use Ignite.Net Tansactions ?

Hi Team,
           Thanks for replying! I hope you might have got some bit of the
background of the requirement from my previous mail. If not, below is the
example of the class that will be consumed by a microservice (A console
app/background service). And using docker there will be multiple instances
of the same service hosted!

In the example below, I have only single operations per function, so do I
really need transactions? Thinking about multiple instance/process
implementation I currently have them, But I am not really sure whether I
really need them, Or having just atomic mode will be fine?

Dose atomic mode guaranty prevention of dirty read and sequential execution?

Scenario 1
If thead1 trying to update tradeid 1 with version 1 started before thread 2
Thread 2 trying to update tradeid 1 with version 2 started after thread 1
(both trying to update the same key)
if there is a race condition wherein trade 1 take time to complete its work,
will thread 2 wait for it?  and commit in a sequential manner even in atomic
mode?


public class TradeCache
    {
        private IIgnite igniteClient { get; set; }
        private ICache<TradeId, TradeDetails> cache { get; set; }

        public TradeCache(IgniteConfiguration configuration)
        {
            igniteClient = Ignition.Start(configuration);
            cache= igniteClient.GetCache<TradeId,
TradeDetails>("TradeDetailsCache");
        }

        public async Task<bool> PutAsync(TradeId tradeId,TradeDetails
tradeDetails)
        {
            using (ITransaction transaction =
igniteClient.GetTransactions().TxStart(
                   TransactionConcurrency.Pessimistic,
TransactionIsolation.RepeatableRead,
                   TimeSpan.FromMilliseconds(300), 0))
            {
                bool result = await cache.PutIfAbsentAsync(tradeId,
tradeDetails);

                transaction.Commit();

                return result;
            }
        }

        public async Task<bool> ReplaceAsync(TradeId tradeId, TradeDetails
tradeDetails)
        {
            using (ITransaction transaction =
igniteClient.GetTransactions().TxStart(
                   TransactionConcurrency.Pessimistic,
TransactionIsolation.RepeatableRead,
                   TimeSpan.FromMilliseconds(300), 0))
            {
                bool result = await cache.ReplaceAsync(tradeId,
tradeDetails);

                transaction.Commit();

                return result;
            }
        }

        public async Task<bool> RemoveAsync(TradeId tradeId)
        {
            using (ITransaction transaction =
igniteClient.GetTransactions().TxStart(
                   TransactionConcurrency.Pessimistic,
TransactionIsolation.RepeatableRead,
                   TimeSpan.FromMilliseconds(300), 0))
            {
                bool result = await cache.RemoveAsync(tradeId);

                transaction.Commit();

                return result;
            }
        }

    }



--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/
ilya.kasnacheev ilya.kasnacheev
Reply | Threaded
Open this post in threaded view
|

Re: When to use Ignite.Net Tansactions ?

Hello!

No, you don't need transactions with just one statement in them, as per your example code.

If you have multiple statements, many things can happen between those 2 statements, such as entries updated and deleted, which might affect your computations in undesirable way. It's up to you to decide whether atomicity is sufficient for you.

In the scenario that you have provided, yes, there will be locking on a key even in ATOMIC mode. Thread will have to wait to complete its operation.

Regards,

--
Ilya Kasnacheev

2018-07-09 13:06 GMT+03:00 Mahesh Talreja <[hidden email]>:
Hi Team,
           Thanks for replying! I hope you might have got some bit of the
background of the requirement from my previous mail. If not, below is the
example of the class that will be consumed by a microservice (A console
app/background service). And using docker there will be multiple instances
of the same service hosted!

In the example below, I have only single operations per function, so do I
really need transactions? Thinking about multiple instance/process
implementation I currently have them, But I am not really sure whether I
really need them, Or having just atomic mode will be fine?

Dose atomic mode guaranty prevention of dirty read and sequential execution?

Scenario 1
If thead1 trying to update tradeid 1 with version 1 started before thread 2
Thread 2 trying to update tradeid 1 with version 2 started after thread 1
(both trying to update the same key)
if there is a race condition wherein trade 1 take time to complete its work,
will thread 2 wait for it?  and commit in a sequential manner even in atomic
mode?


public class TradeCache
    {
        private IIgnite igniteClient { get; set; }
        private ICache<TradeId, TradeDetails> cache { get; set; }

        public TradeCache(IgniteConfiguration configuration)
        {
            igniteClient = Ignition.Start(configuration);
            cache= igniteClient.GetCache<TradeId,
TradeDetails>("TradeDetailsCache");
        }

        public async Task<bool> PutAsync(TradeId tradeId,TradeDetails
tradeDetails)
        {
            using (ITransaction transaction =
igniteClient.GetTransactions().TxStart(
                   TransactionConcurrency.Pessimistic,
TransactionIsolation.RepeatableRead,
                   TimeSpan.FromMilliseconds(300), 0))
            {
                bool result = await cache.PutIfAbsentAsync(tradeId,
tradeDetails);

                transaction.Commit();

                return result;
            }
        }

        public async Task<bool> ReplaceAsync(TradeId tradeId, TradeDetails
tradeDetails)
        {
            using (ITransaction transaction =
igniteClient.GetTransactions().TxStart(
                   TransactionConcurrency.Pessimistic,
TransactionIsolation.RepeatableRead,
                   TimeSpan.FromMilliseconds(300), 0))
            {
                bool result = await cache.ReplaceAsync(tradeId,
tradeDetails);

                transaction.Commit();

                return result;
            }
        }

        public async Task<bool> RemoveAsync(TradeId tradeId)
        {
            using (ITransaction transaction =
igniteClient.GetTransactions().TxStart(
                   TransactionConcurrency.Pessimistic,
TransactionIsolation.RepeatableRead,
                   TimeSpan.FromMilliseconds(300), 0))
            {
                bool result = await cache.RemoveAsync(tradeId);

                transaction.Commit();

                return result;
            }
        }

    }



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