You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ignite.apache.org by Andrey Dolmatov <it...@gmail.com> on 2019/10/24 05:56:56 UTC

Ignite transactions dont work on multiple cache

Hi!
We try to isolate read transaction from write transaction. So, we write to
two transactional caches and commit transaction. From another thread we
read from both caches (READ_COMMITED). Ignite isolate data change for every
single cache, but not for both caches simultaneously.

In Oracle database, for example, transaction include all the tables, you
can read committed data when they appeared in both tables.

I think its very important to show it in documentation.


@Test
public void test_transaction_1() {
    Set<Integer> initial = new HashSet<>();
    for (int i = 0; i < 10000; i++) {
        initial.add(i);
    }


    CacheConfiguration<Integer, Set> config1
            = new CacheConfiguration<>();
    config1.setName("TRANSACTION_CACHE_1");
    config1.setCacheMode(CacheMode.REPLICATED);
    config1.setReadFromBackup(false);
    config1.setOnheapCacheEnabled(true);
    config1.setCopyOnRead(false);
    config1.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);

    CacheConfiguration<Integer, Set> config2
            = new CacheConfiguration<>();
    config2.setName("TRANSACTION_CACHE_2");
    config2.setCacheMode(CacheMode.REPLICATED);
    config2.setReadFromBackup(false);
    config2.setOnheapCacheEnabled(true);
    config2.setCopyOnRead(false);
    config2.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);


    IgniteCache<Integer, Set> cache1 =
igniteClientGate.getOrCreateCache(config1);
    IgniteCache<Integer, Set> cache2 =
igniteClientGate.getOrCreateCache(config2);

    cache1.put(1, initial);
    cache2.put(1, initial);


    CompletableFuture.runAsync(() -> {
        AtomicInteger adder = new AtomicInteger(1);
        while (true) {


            Set<Integer> newSet = new HashSet<>();
            initial.forEach(e -> newSet.add(e + adder.get()));


            try (Transaction tx =
igniteClientLoader.transactions().txStart(TransactionConcurrency.PESSIMISTIC,
TransactionIsolation.REPEATABLE_READ)) {
                cache1.put(1, newSet);
                cache2.put(1, newSet);

                tx.commit();
            }

            adder.incrementAndGet();
        }

    });

    while (true) {

        try (Transaction tx =
igniteClientLoader.transactions().txStart(TransactionConcurrency.PESSIMISTIC,
TransactionIsolation.READ_COMMITTED)) {

            Set set1 = cache1.get(1);
            Set set2 = cache2.get(1);

            if (!set1.equals(set2)) {
                System.out.println("not equals, transaction fails");
            } else {
                System.out.println("equals, transaction works");
            }
            assert set1.equals(set2);

        }

    }


}

Re: Ignite transactions dont work on multiple cache

Posted by Ilya Kasnacheev <il...@gmail.com>.
Hello!

I have noticed that you have READ_COMMITTED isolation when reading. It will
doubtlessly lead to situation when you read value from TXN-1 to set1 while
TXN is in progress, and then will read value from TXN to set2 because it is
committed already.

Don't you see it as a problem?

Regards,
-- 
Ilya Kasnacheev


чт, 24 окт. 2019 г. в 08:57, Andrey Dolmatov <it...@gmail.com>:

> Hi!
> We try to isolate read transaction from write transaction. So, we write to
> two transactional caches and commit transaction. From another thread we
> read from both caches (READ_COMMITED). Ignite isolate data change for every
> single cache, but not for both caches simultaneously.
>
> In Oracle database, for example, transaction include all the tables, you
> can read committed data when they appeared in both tables.
>
> I think its very important to show it in documentation.
>
>
> @Test
> public void test_transaction_1() {
>     Set<Integer> initial = new HashSet<>();
>     for (int i = 0; i < 10000; i++) {
>         initial.add(i);
>     }
>
>
>     CacheConfiguration<Integer, Set> config1
>             = new CacheConfiguration<>();
>     config1.setName("TRANSACTION_CACHE_1");
>     config1.setCacheMode(CacheMode.REPLICATED);
>     config1.setReadFromBackup(false);
>     config1.setOnheapCacheEnabled(true);
>     config1.setCopyOnRead(false);
>     config1.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
>
>     CacheConfiguration<Integer, Set> config2
>             = new CacheConfiguration<>();
>     config2.setName("TRANSACTION_CACHE_2");
>     config2.setCacheMode(CacheMode.REPLICATED);
>     config2.setReadFromBackup(false);
>     config2.setOnheapCacheEnabled(true);
>     config2.setCopyOnRead(false);
>     config2.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
>
>
>     IgniteCache<Integer, Set> cache1 = igniteClientGate.getOrCreateCache(config1);
>     IgniteCache<Integer, Set> cache2 = igniteClientGate.getOrCreateCache(config2);
>
>     cache1.put(1, initial);
>     cache2.put(1, initial);
>
>
>     CompletableFuture.runAsync(() -> {
>         AtomicInteger adder = new AtomicInteger(1);
>         while (true) {
>
>
>             Set<Integer> newSet = new HashSet<>();
>             initial.forEach(e -> newSet.add(e + adder.get()));
>
>
>             try (Transaction tx = igniteClientLoader.transactions().txStart(TransactionConcurrency.PESSIMISTIC, TransactionIsolation.REPEATABLE_READ)) {
>                 cache1.put(1, newSet);
>                 cache2.put(1, newSet);
>
>                 tx.commit();
>             }
>
>             adder.incrementAndGet();
>         }
>
>     });
>
>     while (true) {
>
>         try (Transaction tx = igniteClientLoader.transactions().txStart(TransactionConcurrency.PESSIMISTIC, TransactionIsolation.READ_COMMITTED)) {
>
>             Set set1 = cache1.get(1);
>             Set set2 = cache2.get(1);
>
>             if (!set1.equals(set2)) {
>                 System.out.println("not equals, transaction fails");
>             } else {
>                 System.out.println("equals, transaction works");
>             }
>             assert set1.equals(set2);
>
>         }
>
>     }
>
>
> }
>
>