Hi, I have the CacheConfig.java file generated from the schema import tool. And I am working on a MySql database. So, whenever any updates to the cache is performed, it is updated in the database as well. So, the operations are taking place in the following steps: 1.) Update the cache for k1 from V1 to V2 2.) Write to the database new value of k1 as V2 3.) Reply back to the user
But, what if a user queries the cache, before the 2.) step, say at step 1.1), then old value V1 is returned. How should I modify the code so that if returns value V2, even before V2 has been written to the database? Here's the CacheConfig.java: /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package apache.ignite.schemas; import java.sql.*; import java.util.*; import org.apache.ignite.cache.*; import org.apache.ignite.cache.store.jdbc.*; import org.apache.ignite.configuration.*; /** * CacheConfig definition. * * Code generated by Apache Ignite Schema Import utility: 03/28/2016. */ public class CacheConfig { /** * Create JDBC type for Person. * * @param cacheName Cache name. * @return Configured JDBC type. */ private static JdbcType jdbcTypePerson(String cacheName) { JdbcType jdbcType = new JdbcType(); jdbcType.setCacheName(cacheName); jdbcType.setDatabaseSchema("PERSON"); jdbcType.setDatabaseTable("Person"); jdbcType.setKeyType("apache.ignite.schemas.PersonKey"); jdbcType.setValueType("apache.ignite.schemas.Person"); // Key fields for Person. Collection<JdbcTypeField> keys = new ArrayList<>(); keys.add(new JdbcTypeField(Types.INTEGER, "id", int.class, "id")); jdbcType.setKeyFields(keys.toArray(new JdbcTypeField[keys.size()])); // Value fields for Person. Collection<JdbcTypeField> vals = new ArrayList<>(); vals.add(new JdbcTypeField(Types.INTEGER, "id", int.class, "id")); vals.add(new JdbcTypeField(Types.VARCHAR, "first_name", String.class, "firstName")); vals.add(new JdbcTypeField(Types.VARCHAR, "last_name", String.class, "lastName")); vals.add(new JdbcTypeField(Types.DOUBLE, "salary", double.class, "salary")); jdbcType.setValueFields(vals.toArray(new JdbcTypeField[vals.size()])); return jdbcType; } /** * Create SQL Query descriptor for Person. * * @return Configured query entity. */ private static QueryEntity queryEntityPerson() { QueryEntity qryEntity = new QueryEntity(); qryEntity.setKeyType("apache.ignite.schemas.PersonKey"); qryEntity.setValueType("apache.ignite.schemas.Person"); // Query fields for Person. LinkedHashMap<String, String> fields = new LinkedHashMap<>(); fields.put("id", "int"); fields.put("firstName", "String"); fields.put("lastName", "String"); fields.put("salary", "double"); qryEntity.setFields(fields); // Indexes for Person. Collection<QueryIndex> idxs = new ArrayList<>(); idxs.add(new QueryIndex("id", true, "PRIMARY")); qryEntity.setIndexes(idxs); return qryEntity; } /** * Configure cache. * * @param cacheName Cache name. * @param storeFactory Cache store factory. * @return Cache configuration. */ public static <K, V> CacheConfiguration<K, V> cache(String cacheName, CacheJdbcPojoStoreFactory<K, V> storeFactory) { if (storeFactory == null) throw new IllegalArgumentException("Cache store factory cannot be null."); CacheConfiguration<K, V> ccfg = new CacheConfiguration<>(cacheName); ccfg.setCacheStoreFactory(storeFactory); ccfg.setReadThrough(true); ccfg.setWriteThrough(true); // Configure JDBC types. Collection<JdbcType> jdbcTypes = new ArrayList<>(); jdbcTypes.add(jdbcTypePerson(cacheName)); storeFactory.setTypes(jdbcTypes.toArray(new JdbcType[jdbcTypes.size()])); // Configure query entities. Collection<QueryEntity> qryEntities = new ArrayList<>(); qryEntities.add(queryEntityPerson()); ccfg.setQueryEntities(qryEntities); return ccfg; } } Here's the DemoDemo.java: package apache.ignite.schemas; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.cache.Cache; 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.store.jdbc.CacheJdbcPojoStore; import org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.transactions.Transaction; import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; public class DemoDemo { static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; static final String DB_URL = "jdbc:mysql://localhost/PERSON"; static final String USER = "root"; static final String PASS = "mysql"; /** * Constructs and returns a fully configured instance of a CacheJdbcPojoStoreFactory . */ private static class MySQLDemoStoreFactory<K, V> extends CacheJdbcPojoStoreFactory<K, V> { //{@inheritDoc} @Override public CacheJdbcPojoStore<K, V> create() { MysqlDataSource dataSource = new MysqlDataSource(); dataSource.setURL("jdbc:mysql://localhost/PERSON"); dataSource.setUser("root"); dataSource.setPassword("mysql"); setDataSource(dataSource); return super.create(); } } /** * Executes demo. */ public static void main(String[] args) throws IgniteException { System.out.println(">>> Start demo..."); Connection conn = null; Statement stmt = null; //This block just tests that the database is set up correctly and is able to get/display the values from the table // Register JDBC driver try { Class.forName("com.mysql.jdbc.Driver"); // Open a connection System.out.println("Connecting to database..."); conn = DriverManager.getConnection(DB_URL,USER,PASS); // Execute a query System.out.println("Creating statement..."); stmt = conn.createStatement(); String sql; sql = "SELECT id, first_name, last_name FROM PERSON"; ResultSet rs = stmt.executeQuery(sql); // Extract data from result set while(rs.next()){ //Retrieve by column name int id = rs.getInt("id"); String firstName = rs.getString("first_name"); String lastName = rs.getString("last_name"); //Display values System.out.print("ID: " + id); System.out.print(", First: " + firstName); System.out.println(", Last: " + lastName); } }catch(SQLException se){ //Handle errors for JDBC se.printStackTrace(); }catch(Exception e){ //Handle errors for Class.forName e.printStackTrace(); }finally{ //finally block used to close resources try{ if(stmt!=null) stmt.close(); }catch(SQLException se2){ }// nothing we can do try{ if(conn!=null) conn.close(); }catch(SQLException se){ se.printStackTrace(); } } // Start Ignite node. try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) { // Configure cache store. CacheConfiguration<PersonKey, Person> cfg = CacheConfig.cache("PersonCache", new MySQLDemoStoreFactory<PersonKey, Person>()); try (IgniteCache<PersonKey, Person> cache = ignite.getOrCreateCache(cfg)) { // Preload cache from database. preload(cache); // Read-through from database // and store in cache. readThrough(cache); // Perform transaction and // write-through to database. transaction(ignite, cache); } } } /** * Demonstrates cache preload from database. */ private static void preload(IgniteCache<PersonKey, Person> cache) { System.out.println(); System.out.println(">>> Loading entries from database."); // Preload all person keys that are less than or equal to 3. cache.loadCache(null, PersonKey.class.getName(), "select * from PERSON where ID <= 3"); for (Cache.Entry<PersonKey, Person> person : cache) System.out.println(">>> Loaded Person: " + person); } /** * Demonstrates cache read through from database. */ private static void readThrough(IgniteCache<PersonKey, Person> cache) { PersonKey key = new PersonKey(4); System.out.println(); System.out.println(">>> Read-through person from database for ID: " + key.getId()); // Check that person with ID=4 is not in cache. Person p = cache.localPeek(key); assert p == null; // Read-through from database and store into cache. p = cache.get(new PersonKey(4)); System.out.println(">>> Loaded person from database: " + p); } /** * Demonstrates cache transaction joining database transaction. */ private static void transaction(Ignite ignite, IgniteCache<PersonKey, Person> cache) { PersonKey key = new PersonKey(5); System.out.println(); System.out.println(">>> Update salary and write-through to database for person with ID: " + key.getId()); try (Transaction tx = ignite.transactions().txStart()) { // Read-through from database. Person p = cache.get(key); System.out.println(">>> Loaded person from database: " + p); double salary = p.getSalary(); // Raise salary by 20%. p.setSalary(salary * 1.2); // Write-through to database // and store in cache. cache.put(key, p); System.out.println("xyz"); tx.commit(); } System.out.println(">>> Updated person: " + cache.get(key)); } } -- View this message in context: http://apache-ignite-users.70518.x6.nabble.com/How-to-perform-lazy-write-to-database-tp4002.html Sent from the Apache Ignite Users mailing list archive at Nabble.com.
