I think transactional SQL should be released till the end of the summer 2018-07-24 17:41 GMT+03:00 Maxim Malygin <[email protected]>:
> 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 >>>>> >>>> >>>> >>
