You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ignite.apache.org by Ricky Nauvaldy <ri...@sci.ui.ac.id> on 2017/04/20 02:56:16 UTC
How to do write-behind caching?
Hello, can you provide a tutorial for* write-behind* caching? (similar to
the one on this page https://dzone.com/articles/apache-ignite-how-to-
read-data-from-persistent-sto but for *write-behind*). My configuration is
the same as in the example provided in that page above (MySQL database),
with the transaction process is based on CacheTransactionExample.java
provided in Ignite Examples, but this time I'm trying to learn how to do
*write-behind*. I've already succeed in doing *write through*, but when I
add the *write behind* configuration, it just won't write. What response
should I expect when I use write behind? Will it wait for 5 seconds before
it writes (e.g. using setWriteBehindFlushFrequency(5000) and
setWriteBehindFlushSize(0))?
Thanks for any help that you can provide.
Re: How to do write-behind caching?
Posted by Ricky Nauvaldy Ruliputra <ri...@sci.ui.ac.id>.
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.
Re: How to do write-behind caching?
Posted by Ricky Nauvaldy Ruliputra <ri...@sci.ui.ac.id>.
Figure it out that it's related to the bulk operation in [1], as Andrey
suggested before, in the /jdbc bulk operations/ section, but due to my lack
of experience, I still have to learn a lot . What I have to do is to add
some codes in the /writeAll()/ method in /TransactionStore.java/.
Here's my additional code for /writeAll()/ method to overcome my problem:
@Override
public void writeAll(Collection<Cache.Entry<? extends Long, ? extends
Store>> arg0) throws CacheWriterException {
System.out.println("let me in!");
try(Connection conn = dataSource.getConnection()) {
try (PreparedStatement st = conn.prepareStatement(
"update TRANSACTION set amount = ? where idNumber = ?")) {
for (Entry<? extends Long, ? extends Store> entry : arg0) {
Store val = entry.getValue();
System.out.println("writing: " + val.getIdNumber() + " with " +
val.getAmount() );
st.setLong(2, val.getIdNumber());
st.setLong(1, val.getAmount());
st.addBatch();
}
st.executeBatch();
}
}
catch (SQLException e) {
throw new CacheWriterException("Failed to write object", e);
}
}
Thanks for all the helps. I really appreciate it.
-- Ricky
[1]
https://apacheignite.readme.io/docs/persistent-store#write-behind-caching
--
View this message in context: http://apache-ignite-users.70518.x6.nabble.com/How-to-do-write-behind-caching-tp12138p12280.html
Sent from the Apache Ignite Users mailing list archive at Nabble.com.
Re: How to do write-behind caching?
Posted by Guilherme Melo <gu...@gmelo.org>.
Hello Ricky,
I've had a similar issue, is write through enabled as well?
On 27 Apr 2017 11:14 a.m., "Ricky Nauvaldy Ruliputra" <
ricky.nauvaldy@sci.ui.ac.id> wrote:
> sorry, I pasted the wrong configuration file, I was checking on whether the
> program can write through the database if writeBehindEnabled is turned off.
>
> It should be like this:
>
> <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>
> *it should be like this*
> <property name="writeBehindEnabled"
> 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>
>
> And it's still not writing the data to the persistent store even after I
> waited for 5 seconds. Any suggestion?
>
> --Ricky
>
>
>
> --
> View this message in context: http://apache-ignite-users.
> 70518.x6.nabble.com/How-to-do-write-behind-caching-tp12138p12278.html
> Sent from the Apache Ignite Users mailing list archive at Nabble.com.
>
Re: How to do write-behind caching?
Posted by Ricky Nauvaldy Ruliputra <ri...@sci.ui.ac.id>.
sorry, I pasted the wrong configuration file, I was checking on whether the
program can write through the database if writeBehindEnabled is turned off.
It should be like this:
<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>
*it should be like this*
<property name="writeBehindEnabled"
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>
And it's still not writing the data to the persistent store even after I
waited for 5 seconds. Any suggestion?
--Ricky
--
View this message in context: http://apache-ignite-users.70518.x6.nabble.com/How-to-do-write-behind-caching-tp12138p12278.html
Sent from the Apache Ignite Users mailing list archive at Nabble.com.
Re: How to do write-behind caching?
Posted by Andrey Mashenkov <an...@gmail.com>.
Hi Ricky,
I see no property *writeBehindEnabled=true* in your config.
On Tue, Apr 25, 2017 at 10:02 AM, Ricky Nauvaldy Ruliputra <
ricky.nauvaldy@sci.ui.ac.id> wrote:
> 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-tp12138p12216.html
> Sent from the Apache Ignite Users mailing list archive at Nabble.com.
>
--
Best regards,
Andrey V. Mashenkov
Re: How to do write-behind caching?
Posted by Ricky Nauvaldy Ruliputra <ri...@sci.ui.ac.id>.
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-tp12138p12216.html
Sent from the Apache Ignite Users mailing list archive at Nabble.com.
Re: How to do write-behind caching?
Posted by Ricky Nauvaldy <ri...@sci.ui.ac.id>.
thanks Andrey and Tom for your response. I will try it again.
-- RIcky
On Fri, Apr 21, 2017 at 8:09 PM, Dieds <to...@gridgain.com> wrote:
> A library of tutorials would be just the think for an “Apache Ignite
> University” section. I page of tutorials, how-to’s, videos and local event
> listings. We need one of those on this site.
> Tom
>
>
>
>
>
>
>
> On Apr 21, 2017, at 2:23 AM, Ricky Nauvaldy Ruliputra [via Apache Ignite
> Users] <[hidden email]
> <http:///user/SendEmail.jtp?type=node&node=12153&i=0>> wrote:
>
> Hello, can you provide a tutorial for* write-behind* caching? (similar to
> the one on this page https://dzone.com/articles/apache-ignite-how-to-read-
> data-from-persistent-sto but for *write-behind*). My configuration is the
> same as in the example provided in that page above (MySQL database), with
> the transaction process is based on CacheTransactionExample.java provided
> in Ignite Examples, but this time I'm trying to learn how to do
> *write-behind*. I've already succeed in doing *write through*, but when I
> add the *write behind* configuration, it just won't write. What response
> should I expect when I use write behind? Will it wait for 5 seconds before
> it writes (e.g. using setWriteBehindFlushFrequency(5000) and
> setWriteBehindFlushSize(0))?
>
> Thanks for any help that you can provide.
>
>
> ------------------------------
> If you reply to this email, your message will be added to the discussion
> below:
> http://apache-ignite-users.70518.x6.nabble.com/How-to-do-
> write-behind-caching-tp12138.html
> To unsubscribe from Apache Ignite Users, click here.
> NAML
> <http://apache-ignite-users.70518.x6.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
>
>
>
> ------------------------------
> View this message in context: Re: How to do write-behind caching?
> <http://apache-ignite-users.70518.x6.nabble.com/How-to-do-write-behind-caching-tp12138p12153.html>
> Sent from the Apache Ignite Users mailing list archive
> <http://apache-ignite-users.70518.x6.nabble.com/> at Nabble.com.
>
Re: How to do write-behind caching?
Posted by Dieds <to...@gridgain.com>.
A library of tutorials would be just the think for an “Apache Ignite University” section. I page of tutorials, how-to’s, videos and local event listings. We need one of those on this site.
Tom
> On Apr 21, 2017, at 2:23 AM, Ricky Nauvaldy Ruliputra [via Apache Ignite Users] <ml...@n6.nabble.com> wrote:
>
> Hello, can you provide a tutorial for write-behind caching? (similar to the one on this page https://dzone.com/articles/apache-ignite-how-to-read-data-from-persistent-sto <https://dzone.com/articles/apache-ignite-how-to-read-data-from-persistent-sto> but for write-behind). My configuration is the same as in the example provided in that page above (MySQL database), with the transaction process is based on CacheTransactionExample.java provided in Ignite Examples, but this time I'm trying to learn how to do write-behind. I've already succeed in doing write through, but when I add the write behind configuration, it just won't write. What response should I expect when I use write behind? Will it wait for 5 seconds before it writes (e.g. using setWriteBehindFlushFrequency(5000) and setWriteBehindFlushSize(0))?
>
> Thanks for any help that you can provide.
>
>
> If you reply to this email, your message will be added to the discussion below:
> http://apache-ignite-users.70518.x6.nabble.com/How-to-do-write-behind-caching-tp12138.html <http://apache-ignite-users.70518.x6.nabble.com/How-to-do-write-behind-caching-tp12138.html>
> To unsubscribe from Apache Ignite Users, click here <http://apache-ignite-users.70518.x6.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=1&code=dG9tLmRpZWRlcmljaEBncmlkZ2Fpbi5jb218MXwxNjc1ODU1NTI1>.
> NAML <http://apache-ignite-users.70518.x6.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
--
View this message in context: http://apache-ignite-users.70518.x6.nabble.com/How-to-do-write-behind-caching-tp12138p12153.html
Sent from the Apache Ignite Users mailing list archive at Nabble.com.
Re: How to do write-behind caching?
Posted by Andrey Mashenkov <an...@gmail.com>.
Hi Ricky,
Here is a link to documentation [1].
Write behind will perform in async way. Yes, you should wait 5 sec for
flush.
[1]
https://apacheignite.readme.io/docs/persistent-store#write-behind-caching
On Thu, Apr 20, 2017 at 5:56 AM, Ricky Nauvaldy <ricky.nauvaldy@sci.ui.ac.id
> wrote:
> Hello, can you provide a tutorial for* write-behind* caching? (similar to
> the one on this page https://dzone.com/articles/apache-ignite-how-to-read-
> data-from-persistent-sto but for *write-behind*). My configuration is the
> same as in the example provided in that page above (MySQL database), with
> the transaction process is based on CacheTransactionExample.java provided
> in Ignite Examples, but this time I'm trying to learn how to do
> *write-behind*. I've already succeed in doing *write through*, but when I
> add the *write behind* configuration, it just won't write. What response
> should I expect when I use write behind? Will it wait for 5 seconds before
> it writes (e.g. using setWriteBehindFlushFrequency(5000) and
> setWriteBehindFlushSize(0))?
>
> Thanks for any help that you can provide.
>
--
Best regards,
Andrey V. Mashenkov