Giriş
Şu satırı dahil ederiz
import org.apache.ignite.transaction.Transaction;
Eğer Thin Client kullanıyorsak, ClientTransaction kullanılabilir.
Key-Value API ile 2 farklı transaction kullanılabilir.
1. Pessimistic
2. Optimistic
1. Pessimistic Concurrency
1. Read Committed
Açıklaması şöyle
In Read Committed mode, the locks are acquired before any changes to the data brought by write operations, such as put() or putAll().
2. Repeatable Read
Açıklaması şöyle
The Repeatable Read and Serializable modes are used for situations where locks need to be acquired for both read and write operations.
Örnek
Şöyle yaparız
try (Transaction tx = ignite().transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) {Account acct = cache.get(acctId);assert acct != null;...// Deposit into account.acct.update(amount);// Store updated account in cache.cache.put(acctId, acct);tx.commit();}
3. Serializable
2. Optimistic Concurrency
1. Read Committed - Kullanmayın
2. Repeatable Read - Kullanmayın
3. Serializable - Deadlock Free
Açıklaması şöyle
When using Serializable mode, if data has changed since it was requested by a transaction, the transaction will fail at the prepare phase. In this situation, the developer must code the application behavior on whether or not it should restart the transaction. The two other modes, Repeatable Read and Read Committed, never check if data has changed. Whilst these modes may bring performance benefits, there are no data atomicity guarantees and, therefore, these two modes are rarely used in production applications.
Açıklaması şöyle
When transactions in Ignite are performed with concurrency mode -OPTIMISTIC and isolation level -SERIALIZABLE, locks are acquired during transaction commit with an additional check allowing Ignite to avoid deadlocks.
- Eğer PESSIMISTIC bir kilit varsa zaten başarısız olur
- Eğer OPTIMISTIC READ-COMMITTED veya OPTIMISTIC REPEATABLE-READ ile yazma anı çakışırsa başarısız olur
- Eğer OPTIMISTIC SERIALIZABLE kilit varsa ve sürüm numarası büyükse başarısız olur
Kullanmak için döngü kurulması gerekebilir.
Örnek
Şöyle yaparız
while (true) {try (Transaction tx = ignite.transactions().txStart(TransactionConcurrency.OPTIMISTIC,
TransactionIsolation.SERIALIZABLE)) {Account acct = cache.get(acctId);assert acct != null;...// Deposit into account.acct.update(amount);// Store updated account in cache.cache.put(acctId, acct);tx.commit();// Transaction succeeded. Exiting the loop.break;} catch (TransactionOptimisticException e) {// Transaction has failed. Retry.}}
txStart metodu - Pessimistic Lock
Şöyle yaparız
Ignite ignite = Ignition.ignite(); IgniteTransactions transactions = ignite.transactions(); try (Transaction tx = transactions.txStart()) { Integer hello = cache.get("Hello"); if (hello == 1) { cache.put("Hello", 11); } cache.put("World", 22); tx.commit(); }txStart metodu - Optimistic Lock
Şöyle yaparız. Bu örnek aslında deadlock yaratmak için ancak önemli değil.
Ignite ignite = Ignition.start("/myexamples/config/cluster-config.xml");// Create cache with given name, if it does not exist.final IgniteCache<String, String> cache = ignite.getOrCreateCache("myCache");// populateint i = 0;cache.put(ENTRY1, Integer.toString(i++));cache.put(ENTRY2, Integer.toString(i++));new Thread(() -> {try (Transaction t1 = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) {String val1 = cache.get(ENTRY1);cache.put(ENTRY1, val1 + "b");String val2 = cache.get(ENTRY2);cache.put(ENTRY2, val2 + "b");t1.commit();System.out.println("t1: " + cache.get(ENTRY1));System.out.println("t1: " + cache.get(ENTRY2));}}, "t1-Thread").start();new Thread(() -> {try (Transaction t2 = ignite.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {String val2 = cache.get(ENTRY2);cache.put(ENTRY2, val2 + "c");String val1 = cache.get(ENTRY1);cache.put(ENTRY1, val1 + "c");t2.commit();System.out.println("t2: " + cache.get(ENTRY1));System.out.println("t2: " + cache.get(ENTRY2));}}, "t2-Thread").start();
Hiç yorum yok:
Yorum Gönder