0
votes

I learned the example of apache Ignite. I just want ignite to help to solve distribute transactions. For example。 My account is in DB A, My wife account is in DB B. I want to transfer money to my wife. So the transaction like this :

           IgniteTransactions transactions = ignite.transactions();
           p1.setSalary(500);
           p2_1.setSalary(1500);
           Transaction tx = transactions.txStart(TransactionConcurrency.PESSIMISTIC,TransactionIsolation.SERIALIZABLE);
        
         try {
           cache.put(1L, p1);
           
           cache2.put(1L,p2_1);
           
           tx.commit();
         }catch(Exception e) {
             tx.rollback();
         }

But the cacheStore is like that :

    public void write(Entry<? extends Long, ? extends Person> entry) throws CacheWriterException {
      System.out.println(" +++++++++++  single wirte");
       Long key = entry.getKey();
        Person val = entry.getValue();

        System.out.println(">>> Store write [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 PERSON set orgId = ?, name = ?, salary=?  where id = ?")) {
                st.setLong(1, val.getOrgId());
                st.setString(2, val.getName());
                st.setLong(3, val.getSalary());
                st.setLong(4, val.getId());

                updated = st.executeUpdate();
            }

            // If update failed, try to insert.
            if (updated == 0) {
                try (PreparedStatement st = conn.prepareStatement(
                    "insert into PERSON (id, orgId,name, salary) values (?, ?, ?,?)")) {
                    st.setLong(1, val.getId());
                    st.setLong(2, val.getOrgId());
                    st.setString(3, val.getName());
                    st.setLong(4, val.getSalary());
                    st.executeUpdate();
                }
            }
        }
        catch (SQLException e) {
            throw new CacheWriterException("Failed to write object [key=" + key + ", val=" + val + ']', e);
        }
    
    
}

When the part one commit that the salary updated, the second part failed. part one can not rollback.

How could commit or rollback them simultaneously? does ignite guarantee this or you do it your self?

ps: why ignite said that : it accelerate the transaction? it seems that it only accelerate querys , not deleting or updating operations. because it simultaneously access database when the soft transaction memory happens.

Can somebody figure it out? I don't understand the principle of ignite.

2

2 Answers

0
votes

Ignite does support transactions. But there are two things to consider:

  1. You need to define your cache as TRANSACTIONAL. The default is ATOMIC, which does not support transactions
  2. It does not currently support transactions using SQL. You need to use the key-value API

I’m not sure where you’ve seen it said that Ignite is faster for transactions, but the general principle is that by keeping everything in memory, Ignite can be a lot quicker than legacy databases.

0
votes

Apache Ignite expects that Cache Store does not fail. In your case, the upsert is very fragile and will fail.

At the very least, transactional operations imply transactional cache stores. You need to observe transaction in your cache store, only COMMIT; when told to.