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 <[email protected]>:
> 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 <[email protected]>:
>
> > 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 <
> [email protected]
> > >:
> >
> > > 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 <[email protected]
> >:
> > >
> > > > 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 <
> > > [email protected]
> > > > >:
> > > >
> > > > > Can you please paste the full example?
> > > > >
> > > > > 2017-03-30 11:50 GMT+03:00 ALEKSEY KUZNETSOV <
> > [email protected]
> > > >:
> > > > >
> > > > > > 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 <
> > > > > > [email protected]
> > > > > > >:
> > > > > >
> > > > > > 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" <
> > > > > > [email protected]> написал:
> > > > > >
> > > > > > 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*