Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在ApacheIgnite中隔离事务_Java_Multithreading_Transactions_Isolation Level_Ignite - Fatal编程技术网

Java 如何在ApacheIgnite中隔离事务

Java 如何在ApacheIgnite中隔离事务,java,multithreading,transactions,isolation-level,ignite,Java,Multithreading,Transactions,Isolation Level,Ignite,我试图使用事务同步对Ignite中存储的对象的访问,发现一个事务的结果常常覆盖另一个事务的结果。为了便于测试,我编写了一个更简单的JUnit测试版本: import junit.framework.TestCase; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; import org.apache.ignite.Ignition; import org.apache.ignite.configurat

我试图使用事务同步对Ignite中存储的对象的访问,发现一个事务的结果常常覆盖另一个事务的结果。为了便于测试,我编写了一个更简单的JUnit测试版本:

import junit.framework.TestCase;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.transactions.Transaction;
import org.apache.ignite.transactions.TransactionConcurrency;
import org.apache.ignite.transactions.TransactionIsolation;

public class IgniteTransactionTest extends TestCase {
    private Ignite ignite;

    @Override
    protected void setUp() throws Exception {
        // Start up a non-client Ignite for tests
        IgniteConfiguration config = new IgniteConfiguration();
        ignite = Ignition.getOrStart(config);
    }

    public void testTransaction() throws InterruptedException {
        IgniteCache cache = ignite.getOrCreateCache("cache");
        cache.put("counter", 0);

        Runnable r = () -> {
            for (int i = 0; i < 1000; i++) {
                Transaction tx = ignite.transactions().txStart(
                        TransactionConcurrency.PESSIMISTIC, TransactionIsolation.SERIALIZABLE);

                int counter = (int) cache.get("counter");
                counter += 1;
                cache.put("counter", counter);

                try {
                    tx.commit();
                } catch (Exception ex) {
                    System.out.println("Commit failed");
                    i--;
                }
            }
        };

        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);

        t1.start();
        t2.start();

        t1.join();
        t2.join();

        assertEquals((int) cache.get("counter"), 2000);
    }

    @Override
    protected void tearDown() throws Exception {
        ignite.close();
    }
}
导入junit.framework.TestCase;
导入org.apache.ignite.ignite;
导入org.apache.ignite.IgniteCache;
导入org.apache.ignite.Ignition;
导入org.apache.ignite.configuration.ignite配置;
导入org.apache.ignite.transactions.Transaction;
导入org.apache.ignite.transactions.TransactionConcurrency;
导入org.apache.ignite.transactions.TransactionIsolation;
公共类IgniteTransactionTest扩展了TestCase{
私人点火;
@凌驾
受保护的void setUp()引发异常{
//启动非客户端Ignite进行测试
IgniteConfiguration config=新的IgniteConfiguration();
ignite=Ignition.getOrStart(配置);
}
public void testTransaction()引发InterruptedException{
IgniteCache cache=ignite.getOrCreateCache(“缓存”);
cache.put(“计数器”,0);
可运行r=()->{
对于(int i=0;i<1000;i++){
事务tx=ignite.transactions().txStart(
TransactionConcurrency.悲观、TransactionIsolation.SERIALIZABLE);
int计数器=(int)cache.get(“计数器”);
计数器+=1;
cache.put(“counter”,counter);
试一试{
tx.commit();
}捕获(例外情况除外){
System.out.println(“提交失败”);
我--;
}
}
};
螺纹t1=新螺纹(r);
螺纹t2=新螺纹(r);
t1.start();
t2.start();
t1.join();
t2.连接();
assertEquals((int)cache.get(“计数器”),2000年);
}
@凌驾
受保护的void tearDown()引发异常{
点燃。关闭();
}
}
基本上,它运行两个独立的线程,尝试递增Ignite缓存中存储的计数器(隔离级别可序列化),然后检查计数器是否具有正确的值。根据Ignite交易的规则:

TransactionIsolation.SERIALIZABLE隔离级别意味着所有事务都以完全隔离的方式发生,就好像系统中的所有事务都是连续执行的一样。此级别的读取访问与TransactionIsolation.REPEATABLE_读取级别的读取访问方式相同。但是,在TransactionConcurrency.Optimization模式下,如果某些事务不能相互串行隔离,则将选择一个获胜者,而冲突的其他事务将导致抛出TransactionOptimisticeException

但是运行这个测试会产生

junit.framework.AssertionFailedError:应为:但为:

指示一个线程中的写入可以在另一个线程中的读取和写入之间交错。此外,文档建议失败的事务在尝试提交时应引发异常,但这种情况从未发生


我是否一开始就不理解如何使用事务?如何使它们保持隔离?

您在没有提供缓存配置的情况下创建缓存。默认情况下,已创建原子缓存,此缓存不支持任何事务性功能

您需要这样的smth:

ignite.getOrCreateCache(new CacheConfiguration<>("cache")
    .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL));
ignite.getOrCreateCache(新缓存配置(“缓存”)
.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL));

创建缓存时未提供缓存配置。默认情况下,已创建原子缓存,此缓存不支持任何事务性功能

您需要这样的smth:

ignite.getOrCreateCache(new CacheConfiguration<>("cache")
    .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL));
ignite.getOrCreateCache(新缓存配置(“缓存”)
.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL));