Really? How about DML statements? Regards, Maxim
вт, 24 июл. 2018 г. в 15:06, Evgenii Zhuravlev <[email protected]>: > I'm not sure that this case is valid at all right now, since as for now, > Ignite doesn't support transactions for SQL. > > Evgenii > > 2018-07-24 13:36 GMT+03:00 Maxim Malygin <[email protected]>: > >> Hi Evgenii, >> >> Thanks for the answer. >> Unfortunately it seems it does matter. If I do a query inside a >> transaction and use an instance of a cache that differs of a cache inside >> the query, I will get the following exception (note I do it on client node): >> >> Exception in thread "main" javax.cache.CacheException: Cannot start/stop >> cache within lock or transaction. >> at >> org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.query(IgniteCacheProxyImpl.java:676) >> at >> org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.query(IgniteCacheProxyImpl.java:615) >> at >> org.apache.ignite.internal.processors.cache.GatewayProtectedCacheProxy.query(GatewayProtectedCacheProxy.java:356) >> at simax.test.Startup.main(Startup.java:39) >> Caused by: class org.apache.ignite.IgniteException: Cannot start/stop >> cache within lock or transaction. >> at >> org.apache.ignite.internal.processors.cache.GridCacheProcessor.checkEmptyTransactions(GridCacheProcessor.java:4251) >> at >> org.apache.ignite.internal.processors.cache.GridCacheProcessor.dynamicStartCache(GridCacheProcessor.java:2942) >> at >> org.apache.ignite.internal.processors.cache.GridCacheProcessor.dynamicStartCache(GridCacheProcessor.java:2884) >> at >> org.apache.ignite.internal.processors.cache.GridCacheProcessor.createMissingQueryCaches(GridCacheProcessor.java:4114) >> at >> org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.prepareStatementAndCaches(IgniteH2Indexing.java:2017) >> at >> org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.parseAndSplit(IgniteH2Indexing.java:1796) >> at >> org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.querySqlFields(IgniteH2Indexing.java:1652) >> at >> org.apache.ignite.internal.processors.query.GridQueryProcessor$4.applyx(GridQueryProcessor.java:2035) >> at >> org.apache.ignite.internal.processors.query.GridQueryProcessor$4.applyx(GridQueryProcessor.java:2030) >> at >> org.apache.ignite.internal.util.lang.IgniteOutClosureX.apply(IgniteOutClosureX.java:36) >> at >> org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuery(GridQueryProcessor.java:2578) >> at >> org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:2044) >> at >> org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.query(IgniteCacheProxyImpl.java:664) >> >> It seems the issue is in starting cache used in the query. If I get >> IgniteCache instance for that cache, it will be started before the >> transaction. But if it's never used in Ignite.cache(..) or >> ignite.getOrCreateCache(..), the cache will be started inside query(..) >> method which is executed in the transaction and I will get the above listed >> exception. As workaround, I need to pre-initialize all caches used in >> queries using either Ignite.cache(..) or ignite.getOrCreateCache(..). Note >> that all caches are configured in XML configuration on server nodes only >> but the queries is executed on a client node. >> >> The code is very simple: >> >> public class Startup { >> private static final Logger log = LogManager.getLogger(Startup.class); >> >> public static void main(String[] args) { >> boolean client = args.length >= 1 && >> "client".equalsIgnoreCase(args[0]); >> Ignite ignite; >> if (client) { >> log.info("Starting client node..."); >> ignite = Ignition.start("client.xml"); >> } else { >> log.info("Starting server node..."); >> ignite = Ignition.start("server.xml"); >> } >> log.info("Cache names: " + ignite.cacheNames()); >> IgniteCache<?, ?> cache1 = ignite.cache("Cache1"); >> >> try (Transaction tx = ignite.transactions().txStart()) { >> // query from cache1 using instance of cache1 >> List<List<?>> r1 = cache1.query(new SqlFieldsQuery("SELECT * >> FROM Cache1")).getAll(); // No exception here because Cache1 is already >> initialized by ignite.cache("Cache1") >> log.info("Result from cache1: " + r1); >> } >> >> try (Transaction tx = ignite.transactions().txStart()) { >> // query from cache2 using instance of cache1 >> List<List<?>> r2 = cache1.query(new SqlFieldsQuery("SELECT * >> FROM Cache2")).getAll(); // <<< Got exception here if invoked on client >> node (clientMode=true) >> log.info("Result from cache2: " + r2); >> } >> } >> } >> >> client.xml: >> >> <?xml version="1.0" encoding="UTF-8"?> >> <beans xmlns="http://www.springframework.org/schema/beans" >> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >> xmlns:context="http://www.springframework.org/schema/context" >> xsi:schemaLocation="http://www.springframework.org/schema/beans >> http://www.springframework.org/schema/beans/spring-beans-4.3.xsd"> >> <bean class="org.apache.ignite.configuration.IgniteConfiguration"> >> <property name="clientMode" value="true"/> >> </bean> >> </beans> >> >> server.xml: >> >> <?xml version="1.0" encoding="UTF-8"?> >> <beans xmlns="http://www.springframework.org/schema/beans" >> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >> xmlns:context="http://www.springframework.org/schema/context" >> xsi:schemaLocation="http://www.springframework.org/schema/beans >> http://www.springframework.org/schema/beans/spring-beans-4.3.xsd"> >> <bean class="org.apache.ignite.configuration.IgniteConfiguration"> >> <property name="clientMode" value="false"/> >> <property name="cacheConfiguration"> >> <list> >> <bean >> class="org.apache.ignite.configuration.CacheConfiguration"> >> <property name="name" value="Cache1"/> >> <property name="sqlSchema" value="PUBLIC"/> >> <property name="queryEntities"> >> <list> >> <bean >> class="org.apache.ignite.cache.QueryEntity"> >> <property name="keyType" >> value="Cache1Key"/> >> <property name="keyFields"> >> <set> >> <value>id1</value> >> <value>id2</value> >> </set> >> </property> >> <property name="valueType" >> value="Cache1"/> >> <property name="fields"> >> <map> >> <entry key="id1" >> value="java.lang.String"/> >> <entry key="id2" >> value="java.lang.String"/> >> <entry key="aaa" >> value="java.lang.String"/> >> <entry key="bbb" >> value="java.lang.String"/> >> <entry key="ccc" >> value="java.lang.String"/> >> </map> >> </property> >> </bean> >> </list> >> </property> >> </bean> >> <bean >> class="org.apache.ignite.configuration.CacheConfiguration"> >> <property name="name" value="Cache2"/> >> <property name="sqlSchema" value="PUBLIC"/> >> <property name="queryEntities"> >> <list> >> <bean >> class="org.apache.ignite.cache.QueryEntity"> >> <property name="keyType" >> value="Cache2Key"/> >> <property name="keyFields"> >> <set> >> <value>id3</value> >> <value>id4</value> >> </set> >> </property> >> <property name="valueType" >> value="Cache2"/> >> <property name="fields"> >> <map> >> <entry key="id3" >> value="java.lang.String"/> >> <entry key="id4" >> value="java.lang.String"/> >> <entry key="xxx" >> value="java.lang.String"/> >> <entry key="yyy" >> value="java.lang.String"/> >> <entry key="zzz" >> value="java.lang.String"/> >> </map> >> </property> >> </bean> >> </list> >> </property> >> </bean> >> </list> >> </property> >> </bean> >> </beans> >> >> Maybe I do something incorrectly? >> >> Thanks, >> Maxim >> >> пн, 23 июл. 2018 г. в 17:51, Evgenii Zhuravlev <[email protected] >> >: >> >>> Hi Maxim, >>> >>> It doesn't matter, which cache you will use for SQL queries here, so, >>> yes, you can use some dummy cache. In future, afaik, there are plans to >>> change this API, the method will be placed in Ignite class instead of >>> IgniteCache. >>> >>> Regards, >>> Evgenii >>> >>> 2018-07-23 17:41 GMT+03:00 Maxim Malygin <[email protected]>: >>> >>>> Hi, >>>> >>>> I have the question regarding Java API for SQL queries. >>>> As I understand from the documentation, API for SQL queries is placed >>>> in IgniteCache interface ("query" method). This means that I need to get or >>>> create a cache to do a SQL query. What cache name I should use to get >>>> instance of IgniteCache? Some dummy cache? >>>> >>>> Thanks, >>>> Maxim >>>> >>> >>> >
