I've tried it again but the write behind still doesn't work. Like I said before, if I only use write through, I'm able to write the data to my database, but when I enable write behind, it just won't write even if I wait until 5 seconds (writeBehindFlushFrequency default value). I've read the documentation but couldn't figure it out what's wrong. Would you mind to take a look to my program and see what's wrong in it? I'm afraid that I did something wrong in my configuration.
My table looks like this, in /learnignite/ database, with the table name of /transaction/. +------------+------------+ | idNumber | amount | +------------+------------+ | 1 | 300 | | 2 | 100 | | 3 | 100 | +------------+------------+ *Config file:* /ignite-jdbc.xml/ <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <description>Main Spring file for ignite configuration.</description> <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/learnignite"></property> <property name="username" value="root"></property> <property name="password" value=""></property> </bean> <bean class="org.apache.ignite.configuration.IgniteConfiguration" id="ignite.cfg"> <property name="cacheConfiguration"> <list> <bean class="org.apache.ignite.configuration.CacheConfiguration"> <property name="name" value="transactionCache"></property> <property name="readThrough" value="true"></property> <property name="writeThrough" value="true"></property> <property name="queryEntities"> <list> <bean class="org.apache.ignite.cache.QueryEntity"> <property name="keyType" value="java.lang.Long"></property> <property name="valueType" value="ignite.myexamples.model.Store"></property> <property name="fields"> <map> <entry key="idNumber" value="java.lang.Integer"></entry> <entry key="amount" value="java.lang.Integer"></entry> </map> </property> </bean> </list> </property> <property name="cacheStoreFactory"> <bean class="javax.cache.configuration.FactoryBuilder" factory-method="factoryOf"> <constructor-arg value="myexamples.store.TransactionStore"></constructor-arg> </bean> </property> </bean> </list> </property> <property name="discoverySpi"> <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> <property name="ipFinder"> <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder"> <property name="multicastGroup" value="228.10.10.157"/> <property name="addresses"> <list> <value>localhost/127.0.0.1:3306</value> </list> </property> </bean> </property> </bean> </property> </bean> </beans> *Model file:* /Store.java/ package ignite.myexamples.model; public class Store { private int idNumber; private int amount; public void update(double deposit) { amount += deposit; } public Store(int idNumber, int amount) { super(); this.idNumber = idNumber; this.amount = amount; } public long getIdNumber() { return idNumber; } public void setIdNumber(int idNumber) { this.idNumber = idNumber; } public long getAmount() { return amount; } public void setAmount(int amount) { this.amount = amount; } @Override public String toString() { return "Transaction [idNumber=" + idNumber + ", amount=" + amount + "]"; } } /*TransactionStore.java*/ package myexamples.store; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collection; import java.util.Map; import javax.cache.Cache.Entry; import javax.cache.integration.CacheLoaderException; import javax.cache.integration.CacheWriterException; import javax.sql.DataSource; import org.apache.ignite.cache.store.CacheStore; import org.apache.ignite.lang.IgniteBiInClosure; import org.apache.ignite.resources.SpringResource; import org.jetbrains.annotations.Nullable; import ignite.myexamples.model.Store; public class TransactionStore implements CacheStore<Long, Store> { @SpringResource(resourceName = "dataSource") private DataSource dataSource; // This method is called whenever IgniteCache.loadCache() method is called. @Override public void loadCache(IgniteBiInClosure<Long, Store> clo, @Nullable Object... objects) throws CacheLoaderException { System.out.println(">> Loading cache from store..."); try (Connection conn = dataSource.getConnection()) { try (PreparedStatement st = conn.prepareStatement("select * from TRANSACTION")) { // dari tabel mysql try (ResultSet rs = st.executeQuery()) { while (rs.next()) { Store transaksi = new Store(rs.getInt(1), rs.getInt(2)); clo.apply(transaksi.getIdNumber(), transaksi); } } } } catch (SQLException e) { throw new CacheLoaderException("Failed to load values from cache store.", e); } } // This method is called whenever IgniteCache.get() method is called. @Override public Store load(Long key) throws CacheLoaderException { System.out.println("Loading Transaction from Store ..."); try (Connection conn = dataSource.getConnection()) { try (PreparedStatement st = conn.prepareStatement("select * from TRANSACTION where id = ?")) { st.setString(1, key.toString()); ResultSet rs = st.executeQuery(); return rs.next() ? new Store(rs.getInt(1), rs.getInt(2)) : null; } } catch (SQLException e) { throw new CacheLoaderException("Failed to load values from cache store.", e); } } @Override public Map<Long, Store> loadAll(Iterable<? extends Long> arg0) throws CacheLoaderException { // TODO Auto-generated method stub return null; } @Override public void delete(Object arg0) throws CacheWriterException { // TODO Auto-generated method stub } @Override public void deleteAll(Collection<?> arg0) throws CacheWriterException { // TODO Auto-generated method stub } @Override public void write(Entry<? extends Long, ? extends Store> arg0) throws CacheWriterException { // TODO Auto-generated method stub Long key = arg0.getKey(); Store val = arg0.getValue(); System.out.println(">>> Store write "); System.out.println("[key=" + key + ", val=" + val + ']'); try { Connection conn = dataSource.getConnection(); int updated; // Try update first. If it does not work, then try insert. // Some databases would allow these to be done in one 'upsert' operation. try (PreparedStatement st = conn.prepareStatement( "update TRANSACTION set amount = ? where idNumber = ?")) { st.setLong(1, val.getAmount()); st.setLong(2, val.getIdNumber()); updated = st.executeUpdate(); System.out.println("update success"); } if (updated == 0) { try (PreparedStatement st = conn.prepareStatement( "insert into TRANSACTION (id, amount) values (?, ?)")) { st.setLong(1, val.getIdNumber()); st.setLong(2, val.getAmount()); st.executeUpdate(); System.out.println("insertion success"); } } } catch (SQLException e) { throw new CacheWriterException("Failed to write object [key=" + key + ", val=" + val + ']', e); } } @Override public void writeAll(Collection<Entry<? extends Long, ? extends Store>> arg0) throws CacheWriterException { // TODO Auto-generated method stub } @Override public void sessionEnd(boolean commit) throws CacheWriterException { // TODO Auto-generated method stub } } *Server node:* /TransactionServer.java/ package myexamples.store; import java.util.List; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; import org.apache.ignite.IgniteException; import org.apache.ignite.Ignition; import org.apache.ignite.cache.query.QueryCursor; import org.apache.ignite.cache.query.SqlFieldsQuery; import ignite.myexamples.model.Store; public class TransactionServer { public static void main(String[] args) throws IgniteException { // Start Ignite node. Ignite ignite = Ignition.start("path/to/my/ignite-jdbc.xml"); IgniteCache<Long, Store> cache = ignite.getOrCreateCache("transactionCache"); // Load cache with data from the database. cache.loadCache(null); // Execute query on cache. QueryCursor<List<?>> cursor = cache.query(new SqlFieldsQuery( "select idNumber, amount from Store")); System.out.println(cursor.getAll()); } } *Client node:* /TransactionStoreExample.java/ package myexamples.store; import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC; import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; import org.apache.ignite.IgniteException; import org.apache.ignite.Ignition; import org.apache.ignite.transactions.Transaction; import ignite.myexamples.model.Store; public class TransactionStoreExample { public static void main(String[] args) throws IgniteException { // In this case, I just try the number 1 and add it with the amount of 100 long id = 1; long amount = 100; // Set it as a client Ignition.setClientMode(true); // Start Ignite node. try (Ignite ignite = Ignition.start("path/to/my/ignite-jdbc.xml")) { try (IgniteCache<Long, Store> igniteCache = ignite.getOrCreateCache("transactionCache")) { try (Transaction tx = ignite.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { Store account = igniteCache.get((long) id); assert account != null; // update amount account.update(amount); // Store updated account in cache. igniteCache.put(id, account); tx.commit(); System.out.println(igniteCache.get(id)); } } } } } Thanks for any help that you can provide. -- Ricky -- View this message in context: http://apache-ignite-users.70518.x6.nabble.com/How-to-do-write-behind-caching-tp12138p12215.html Sent from the Apache Ignite Users mailing list archive at Nabble.com.
