我試圖使用事務來同步對存儲在Ignite中的對象的訪問,並發現一個事務的結果經常覆蓋另一個事務的結果。我已經寫了什麼我想爲便於測試做一個JUnit測試一個簡單的版本:如何隔離Apache Ignite中的事務
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();
}
}
基本上,它運行兩個獨立的線程試圖增加存儲在緩存中點燃一個計數器,隔離級別爲SERIALIZABLE,然後檢查計數器是否具有正確的值。按照documentation爲Ignite交易:
TransactionIsolation.SERIALIZABLE isolation level means that all transactions occur in a completely isolated fashion, as if all transactions in the system had executed serially, one after the other. Read access with this level happens the same way as with TransactionIsolation.REPEATABLE_READ level. However, in TransactionConcurrency.OPTIMISTIC mode, if some transactions cannot be serially isolated from each other, then one winner will be picked and the other transactions in conflict will result in TransactionOptimisticException being thrown.
但運行這個測試產生
junit.framework.AssertionFailedError: expected:<1613> but was:<2000>
表明在一個線程寫入可以讀取,並在其他線程寫入之間交錯。此外,文檔還建議失敗的事務在嘗試提交時應該引發異常,但這種情況永遠不會發生。
我想知道如何使用交易的第一個地方?我如何讓他們孤立?