The previous article describes how to install and use the Ignite cache. Today talk about Ignite cache transactions.
In our usual development there is often a scenario where two or more threads are simultaneously manipulating a cached data, at which point we want either to succeed or fail. This kind of scene is very common in the database of the number relation, it is realized through the transaction processing of the data base. Let's take a look at how Ignite can implement this transaction.
Let's look at a test program first.
Package My.ignitestudy.datagrid;
Import Org.apache.ignite.Ignite;
Import Org.apache.ignite.IgniteCache;
Import org.apache.ignite.Ignition;
Import Org.apache.ignite.cache.CacheAtomicityMode;
Import org.apache.ignite.configuration.AtomicConfiguration;
Import org.apache.ignite.configuration.CacheConfiguration;
Import org.apache.ignite.configuration.IgniteConfiguration;
Import Org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
Import Org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
Import org.apache.ignite.transactions.Transaction;
Import org.apache.ignite.transactions.TransactionConcurrency;
Import org.apache.ignite.transactions.TransactionIsolation;
Import Java.util.Arrays; public class Transactionexample {public static void main (string[] args) throws Exception {testtransaction (
);
private static Ignite Getignite () {Tcpdiscoveryspi SPI = new Tcpdiscoveryspi (); Tcpdiscoveryvmipfinder Ipfinder = new TcpdiscoveryvmipfindER ();
Ipfinder.setaddresses (Arrays.aslist ("192.168.0.192:47500..47509"));
Spi.setipfinder (Ipfinder);
Igniteconfiguration cfg = new igniteconfiguration ();
CFG.SETDISCOVERYSPI (SPI);
Cfg.setclientmode (TRUE);
Ignite Ignite = Ignition.start (CFG);
return ignite;
private static void Testtransaction () throws Exception {final Ignite Ignite = Getignite ();
Cacheconfiguration cachecfg = new Cacheconfiguration ();
Cachecfg.setname ("Default");
Cachecfg.setatomicitymode (cacheatomicitymode.transactional);
Cachecfg.setbackups (1);
Final ignitecache<string, string> cache = Ignite.getorcreatecache (cachecfg);
Cache.remove ("MyKey"); New Thread (New Runnable () {@Override public void run () {System.out.println ("Tran
Saction 1:begin "); Try (Transaction tx = Ignition.ignite (). transactions (). Txstart (TransactionconcurrenCy.
Optimistic, transactionisolation.serializable)) {String value = Cache.get ("MyKey");
Cache.put ("MyKey", "MyValue 1");
try {thread.currentthread (). Sleep (5 * 1000);
catch (Interruptedexception e) {e.printstacktrace ();
} System.out.println ("Transaction 1:before Commit," + cache.get ("MyKey"));
Tx.commit ();
System.out.println ("Transaction 1:after Commit," + cache.get ("MyKey"));
} System.out.println ("Transaction 1:end");
}). Start ();
Thread.CurrentThread (). Sleep (2 * 1000); New Thread (New Runnable () {@Override public void run () {System.out.println ("Tran
Saction 2:begin "); Try (Transaction tx = Ignition.ignite (). transactions (). Txstart (TransactioncoNcurrency.
Optimistic, transactionisolation.serializable)) {String value = Cache.get ("MyKey");
Cache.put ("MyKey", "MyValue 2");
System.out.println ("Transaction 2:before Commit," + cache.get ("MyKey"));
Tx.commit ();
System.out.println ("Transaction 2:after Commit," + cache.get ("MyKey"));
} System.out.println ("Transaction 2:end");
}). Start (); }
}
The test program uses two threads to manipulate a cache at the same time. And the second thread runs later, in order to wait for the first thread to modify the data first, in order to make it easier to test our program. To use the Ignite transaction, you need to configure the atomic schema to "Cacheatomicitymode.transactional", which can also be specified in the configuration file.
Java
Cachecfg.setatomicitymode (cacheatomicitymode.transactional);
The transaction is created by using the Ignition.ignite (). transactions (). Txstart (Transactionconcurrency, transactionisolation). Where the transactional concurrency pattern transactionconcurrency can be optimistic or pessimistic. Transaction-level transactionisolation can be read-committed,repeatable_read and SERIALIZABLE. In our scenario of using transactions, we can tailor the transaction concurrency pattern and transaction level parameters to meet the needs of our different businesses. The transaction may end up with a commit () to commit the modification, or to roll back and forth the modification by rollback ().
Run the test program, you can see the first thread modified the cache, but did not commit the modification, but wait until the second thread commits the modification, at this time the first thread throws an exception, rollback modified.