Note that you call doInTransaction() for ignite(1), but you have acquired
the cache reference for ignite(0), thus your cache.put() commits
immediately from another node, because transactional scope is node-local.

If you change the test either to use ignite(0) for doInTransaction, or to
get the cache in the callable like ignite(1).cache("testCache"), the test
will not throw an exception. Note that it will hang because doInTrasaction
starts a pessimistic transaction which acquires a lock on key1, and then
you put it to infinite sleep. The lock prevents the transaction from
the main thread to commit.

2017-03-30 15:44 GMT+03:00 ALEKSEY KUZNETSOV <alkuznetsov...@gmail.com>:

> I've edited code and now DIRTY READ occures!
>
> Ignite ignite0 = ignite(0);
> IgniteTransactions transactions = ignite0.transactions();
> IgniteCache<String, String> cache = ignite0.getOrCreateCache("testCache");
> Object monitor = new Object();
>
> GridTestUtils.runAsync(new Callable<Object>() {
>     @Override
>     public Object call() throws Exception {
>             doInTransaction(ignite(1), new Callable<Object>() {
>                 @Override
>                 public Object call() throws Exception {
>                     synchronized (monitor) {
>                         cache.put("key1", "val1!");
>                         monitor.wait();
>                         fail();
>                         return null;
>                     }
>             }
>             });
>         return null;
>     }
> });
> Thread.currentThread().sleep(1000);<------ dirty read occures only if
> we sleep some time !
> Transaction tx =
> transactions.txStart(TransactionConcurrency.OPTIMISTIC,
> TransactionIsolation.READ_COMMITTED);
> String key1Value = cache.get("key1");
> if(key1Value.equals("val1!"))
>     throw new RuntimeException("dirty read!");<------ exception does
> happen!
> cache.put("key1", "val1");
> cache.put("key2", "val2");
> cache.put("key3", "val3");
> tx.commit();
>
>
> чт, 30 мар. 2017 г. в 14:04, Alexey Goncharuk <alexey.goncha...@gmail.com
> >:
>
> > Agree, the cache is transactional, however, the second transaction does
> not
> > see the dirty value:
> >
> > Ignite ignite0 = ignite(0);
> > IgniteTransactions transactions = ignite0.transactions();
> > final IgniteCache<String, String> cache =
> >     ignite0.getOrCreateCache("testCache");
> >
> > final Object monitor = new Object();
> >
> > GridTestUtils.runAsync(new Callable<Object>() {
> >     @Override
> >     public Object call() throws Exception {
> >         synchronized (monitor){
> >             doInTransaction(ignite(1), new Callable<Object>() {
> >                 @Override
> >                 public Object call() throws Exception {
> >                     cache.put("key1", "val1");
> >                     monitor.wait();
> >                     System.out.println("continue first transaction");
> >                     return null;
> >                 }
> >             });
> >         }
> >         return null;
> >     }
> > });
> >
> > Transaction tx =
> >     transactions.txStart(TransactionConcurrency.OPTIMISTIC,
> >         TransactionIsolation.READ_COMMITTED);
> > assertNull(cache.get("key1")); // <- This check passes
> > tx.commit();
> >
> >
> > 2017-03-30 13:30 GMT+03:00 ALEKSEY KUZNETSOV <alkuznetsov...@gmail.com>:
> >
> > > Well, i changed code , added :
> > >
> > > CacheConfiguration config = cache.getConfiguration(
> > > CacheConfiguration.class);
> > > System.out.println(config.getAtomicityMode());//TRANSACTIONAL
> > >
> > > So, atomicity is transactional
> > >
> > > чт, 30 мар. 2017 г. в 12:43, Alexey Goncharuk <
> > alexey.goncha...@gmail.com
> > > >:
> > >
> > > > Aleksey,
> > > >
> > > > It looks like in your test the result of method atomicityMode() is
> not
> > > used
> > > > because you do getOrCreateCache() without the configuration argument,
> > > which
> > > > will create a cache with a default configuration, which is ATOMIC.
> > > >
> > > > 2017-03-30 12:06 GMT+03:00 ALEKSEY KUZNETSOV <
> alkuznetsov...@gmail.com
> > >:
> > > >
> > > > > public class FooTest extends GridCacheAbstractSelfTest {
> > > > >
> > > > >     @Override
> > > > >     protected void afterTestsStopped() throws Exception {
> > > > >         super.afterTestsStopped();
> > > > >         stopAllGrids();
> > > > >     }
> > > > >
> > > > >     @Override
> > > > >     protected int gridCount() {
> > > > >         return 3;
> > > > >     }
> > > > >
> > > > >     @Override
> > > > >     protected CacheMode cacheMode() {
> > > > >         return CacheMode.PARTITIONED;
> > > > >     }
> > > > >
> > > > >     @Override
> > > > >     protected CacheAtomicityMode atomicityMode() {
> > > > >         return CacheAtomicityMode.TRANSACTIONAL;
> > > > >     }
> > > > >
> > > > >     public void testLoggingTransactions() throws
> > InterruptedException {
> > > > >         Ignite ignite0 = ignite(0);
> > > > >         IgniteTransactions transactions = ignite0.transactions();
> > > > >         IgniteCache<String, String> cache =
> > > > > ignite0.getOrCreateCache("testCache");
> > > > >         Object monitor = new Object();
> > > > >
> > > > >         GridTestUtils.runAsync(new Callable<Object>() {
> > > > >             @Override
> > > > >             public Object call() throws Exception {
> > > > >                 synchronized (monitor){
> > > > >                     doInTransaction(ignite(1), new
> > Callable<Object>() {
> > > > >                         @Override
> > > > >                         public Object call() throws Exception {
> > > > >                             cache.put("key1", "val1");
> > > > >                             monitor.wait();
> > > > >                             System.out.println("continue first
> > > > > transaction");
> > > > >                             return null;
> > > > >                         }
> > > > >                     });
> > > > >                 }
> > > > >                 return null;
> > > > >             }
> > > > >         });
> > > > >
> > > > >         Transaction tx =
> > > > > transactions.txStart(TransactionConcurrency.OPTIMISTIC,
> > > > > TransactionIsolation.READ_COMMITTED);
> > > > >         cache.put("key1", "val1");
> > > > >         cache.put("key2", "val2");
> > > > >         cache.put("key3", "val3");
> > > > >         tx.commit();
> > > > >
> > > > >     }
> > > > > }
> > > > >
> > > > >
> > > > > чт, 30 мар. 2017 г. в 11:55, Alexey Goncharuk <
> > > > alexey.goncha...@gmail.com
> > > > > >:
> > > > >
> > > > > > Can you please paste the full example?
> > > > > >
> > > > > > 2017-03-30 11:50 GMT+03:00 ALEKSEY KUZNETSOV <
> > > alkuznetsov...@gmail.com
> > > > >:
> > > > > >
> > > > > > > But i managed to read dirty. That is my example :
> > > > > > >
> > > > > > > Ignite ignite0 = ignite(0);
> > > > > > > IgniteTransactions transactions = ignite0.transactions();
> > > > > > > IgniteCache<String, String> cache =
> > > > > > ignite0.getOrCreateCache("testCache");
> > > > > > > Object monitor = new Object();
> > > > > > >
> > > > > > > GridTestUtils.runAsync(new Callable<Object>() {
> > > > > > >     @Override
> > > > > > >     public Object call() throws Exception {
> > > > > > >         synchronized (monitor){
> > > > > > >             doInTransaction(ignite(1), new Callable<Object>() {
> > > > > > >                 @Override
> > > > > > >                 public Object call() throws Exception {
> > > > > > >                     cache.put("key1", "val1");
> > > > > > >                     monitor.wait();
> > > > > > >                     return null;
> > > > > > >                 }
> > > > > > >             });
> > > > > > >         }
> > > > > > >         return null;
> > > > > > >     }
> > > > > > > });
> > > > > > >
> > > > > > > Transaction tx =
> > > > > > > transactions.txStart(TransactionConcurrency.OPTIMISTIC,
> > > > > > > TransactionIsolation.READ_COMMITTED);
> > > > > > > cache.put("key1", "val1");
> > > > > > >
> > > > > > > And through debugging cache.put() method i can see in method
> > > > > > > *org.apache.ignite.internal.processors.cache.distributed.
> > > > > > > near.GridNearTxLocal#enlistWriteEntry*
> > > > > > > that "key1" already *EXISTS *in internal cache :
> > > > > > cacheCtx.cache().entryEx()
> > > > > > > returns not null.
> > > > > > >
> > > > > > > ср, 29 мар. 2017 г. в 20:11, Alexander Fedotov <
> > > > > > > alexander.fedot...@gmail.com
> > > > > > > >:
> > > > > > >
> > > > > > > Hello Aleksey,
> > > > > > >
> > > > > > > No, the enlisted entry won't be visible for other transactions.
> > > Dirty
> > > > > > reads
> > > > > > > are not allowed in Ignite.
> > > > > > >
> > > > > > > Kind regards,
> > > > > > > Alex
> > > > > > >
> > > > > > > 29 марта 2017 г. 7:36 PM пользователь "ALEKSEY KUZNETSOV" <
> > > > > > > alkuznetsov...@gmail.com> написал:
> > > > > > >
> > > > > > > Hello, Igniters! I have one more question to you. Will
> appreciate
> > > any
> > > > > > help.
> > > > > > > Consider cache with near , dht configured not null.
> > > > > > > When we start commit transaction , in method
> > > > > > > *org.apache.ignite.internal.processors.cache.distributed.
> > > > > > > near.GridNearTxLocal#enlistWriteEntry*
> > > > > > > we put newly created entry into cache by executing entryEx().
> > > > > > > I wonder if this entry will became visible for other
> > transactions!?
> > > > > > > --
> > > > > > >
> > > > > > > *Best Regards,*
> > > > > > >
> > > > > > > *Kuznetsov Aleksey*
> > > > > > >
> > > > > > > --
> > > > > > >
> > > > > > > *Best Regards,*
> > > > > > >
> > > > > > > *Kuznetsov Aleksey*
> > > > > > >
> > > > > >
> > > > > --
> > > > >
> > > > > *Best Regards,*
> > > > >
> > > > > *Kuznetsov Aleksey*
> > > > >
> > > >
> > > --
> > >
> > > *Best Regards,*
> > >
> > > *Kuznetsov Aleksey*
> > >
> >
> --
>
> *Best Regards,*
>
> *Kuznetsov Aleksey*
>

Reply via email to