0

I am using Ignite 2.13.x for one of my requirement, I need to maintain cache in Ignite cluster and some of the keys value will be updates concurrently and selection also happens parallel. So here i am facing issue like,

java.sql.SQLException: Failed to update some keys because they had been modified concurrently [keys=[ROWKEY [idHash=628930863, hash=1637498765, rowkey=6, id=765436]]] at org.apache.ignite.internal.jdbc.thin.JdbcThinConnection.sendRequest(JdbcThinConnection.java:1009) at org.apache.ignite.internal.jdbc.thin.JdbcThinStatement.execute0(JdbcThinStatement.java:234) at org.apache.ignite.internal.jdbc.thin.JdbcThinPreparedStatement.executeWithArguments(JdbcThinPreparedStatement.java:252) at org.apache.ignite.internal.jdbc.thin.JdbcThinPreparedStatement.executeUpdate(JdbcThinPreparedStatement.java:96) at sun.reflect.GeneratedMethodAccessor56.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:118) at com.sun.proxy.$Proxy16.executeUpdate(Unknown Source)

This was the configuration using at server side,

        <bean class="org.apache.ignite.configuration.IgniteConfiguration"
            id="igniteConfiguration">
            
            <property name="cacheKeyConfiguration">
                <list>
                    <bean class="org.apache.ignite.cache.CacheKeyConfiguration">
                        <property name="typeName" value="ROWKEY" />
                        <property name="affinityKeyFieldName" value="rowkey" />
                    </bean>
                </list>
            </property>
    
            <property name="clientMode" value="false" />
            <property name="gridName" value="6d-ignite-grid"></property>
            <property name="cacheConfiguration">
                <list>
                    <bean class="org.apache.ignite.configuration.CacheConfiguration">
                        <property name="name" value="persons"></property>
                        <!-- Set cache mode. -->
                        <property name="cacheMode" value="PARTITIONED" />
                        <!-- Set number of backups to 0 -->
                        <property name="backups" value="0" />
                        <property name="onheapCacheEnabled" value="false" />
                        <property name="statisticsEnabled" value="true" />
                        <property name="memoryPolicyName" value="Default_Region" />
                        <property name="copyOnRead" value="false" />
                        <property name="writeSynchronizationMode" value="FULL_SYNC" />
                        <property name="affinity">
                            <bean
                                class="org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction">
                                <property name="excludeNeighbors" value="true" />
                                <property name="partitions" value="10" />
                                <property name="affinityBackupFilter">
                                    <bean
                                        class="org.apache.ignite.cache.affinity.rendezvous.ClusterNodeAttributeAffinityBackupFilter">
                                        <constructor-arg>
                                            <array value-type="java.lang.String">
                                                <value>AVAILABILITY_ZONE</value>
                                            </array>
                                        </constructor-arg>
                                    </bean>
                                </property>
                            </bean>
                        </property>

                        <property name="queryEntities">
                            <list>
                                <bean class="org.apache.ignite.cache.QueryEntity">
                                    <property name="keyType" value="ROWKEY"></property>
                                    <property name="valueType" value="PERSONS"></property>
                                    <property name="fields">
                                        <map>
                                            <entry key="rowkey" value="java.lang.Long"></entry>
                                            <entry key="id" value="java.lang.Long"></entry>
                                            <entry key="name" value="java.lang.String"></entry>
                                            <entry key="birthday" value="java.lang.String"></entry>
                                            <entry key="gender" value="java.lang.String"></entry>
                                            <entry key="amount" value="java.lang.Long"></entry>
                                            <entry key="salary" value="java.lang.Long"></entry>
                                            <entry key="orgid" value="java.lang.String"></entry>
                                        </map>
                                    </property>
                                    <property name="keyFields">
                                        <set>
                                            <value>rowkey</value>
                                            <value>id</value>
                                        </set>
                                    </property>
                                </bean>
                            </list>
                        </property>
                    </bean>
                </list>
            </property>
            <property name="includeEventTypes">
                <list>
                    <!--Task execution events -->
                    <util:constant
                        static-field="org.apache.ignite.events.EventType.EVT_TASK_STARTED" />
                    <util:constant
                        static-field="org.apache.ignite.events.EventType.EVT_TASK_FINISHED" />
                    <util:constant
                        static-field="org.apache.ignite.events.EventType.EVT_TASK_FAILED" />
                    <util:constant
                        static-field="org.apache.ignite.events.EventType.EVT_TASK_TIMEDOUT" />
                    <util:constant
                        static-field="org.apache.ignite.events.EventType.EVT_TASK_SESSION_ATTR_SET" />
                    <util:constant
                        static-field="org.apache.ignite.events.EventType.EVT_TASK_REDUCED" />

                    <!--Cache events -->
                    <util:constant
                        static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT" />
                    <util:constant
                        static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_READ" />
                    <util:constant
                        static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_REMOVED" />
                </list>
            </property>
            <property name="peerClassLoadingEnabled" value="true"></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="addresses">
                                <list>
                                    <!-- In distributed environment, replace with actual host IP address. -->
                                    <value>127.0.0.1:47500..47509</value>
                                    
                                </list>
                            </property>
                        </bean>
                    </property>
                </bean>
            </property>

            <property name="memoryConfiguration">
                <bean class="org.apache.ignite.configuration.MemoryConfiguration">
                    <property name="defaultMemoryPolicyName" value="Default_Region" />
                    <property name="pageSize" value="4096" />
                    <property name="systemCacheInitialSize" value="#{40 * 1024 * 1024}" />
                    <property name="systemCacheMaxSize" value="#{40 * 1024 * 1024}" />
                    <property name="memoryPolicies">
                        <list>
                            <bean
                                class="org.apache.ignite.configuration.MemoryPolicyConfiguration">
                                <property name="name" value="Default_Region" />
                                <property name="initialSize" value="#{20 * 1024 * 1024}" />
                                <property name="maxSize" value="#{20 * 1024 * 1024}" />
                                <property name="pageEvictionMode" value="RANDOM_2_LRU" />
                                <property name="evictionThreshold" value="0.6" />
                                <property name="metricsEnabled" value="true" />
                            </bean>
                        </list>
                    </property>
                </bean>
            </property>
        </bean>
    

Thanks for help Ajay Babu Maguluri.

Ajay
  • 47
  • 4

1 Answers1

0

The error message indicates that the value was updated in parallel during the operation execution and the failed operation should be retried. It's expected to get such a type of error in the case of concurrent atomic updates for the same key in the cache. Or you can use transactions as an alternative way to avoid that.

Also, you can find more details regarding cache atomicity modes here: https://ignite.apache.org/docs/latest/configuring-caches/atomicity-modes#atomicity-modes

Igor Belyakov
  • 788
  • 4
  • 9
  • Thanks for reply, here i am using JDBC client to query the data from cache, as i seen in 2.13.x doc TRANSACTIONAL : SQL transactions are not supported & TRANSACTIONAL_SNAPSHOT :deprecated in 2.12.x. How to handle this? any client side properties can enable in jdbc url? – Ajay Jun 21 '22 at 18:47
  • I guess that Igor proposed to use Java API for transactions. Concerning your case I guess that you can also try to use `writeSynchronizationMode=PRIMARY_SYNC` thus reducing intersection between different write attempts – solveMe Jun 22 '22 at 00:26
  • Thanks for relpy.Still getting same exception with , here update queries will execute parallel from more JDBC clients. – Ajay Jun 22 '22 at 10:48
  • Hello Team, Please update. Any roadmap will be solved in upcoming releases. In case of exception, if we want to re-try any specific exception type will throw, so that will catch and do the re-try specific case. – Ajay Jun 24 '22 at 06:14
  • @Ajay how did you resolve the issue? – praveen sangalad Oct 26 '22 at 20:41
  • @praveensangalad not yet resolved. Any update from Ignite you found. – Ajay Dec 16 '22 at 09:51