/**
   * @param gridName Grid name.
   * @return Cache configuration.
   * @throws Exception In case of error.
   */
  @SuppressWarnings("unchecked")
  protected CacheConfiguration cacheConfiguration(String gridName) throws Exception {
    CacheConfiguration cfg = defaultCacheConfiguration();

    CacheStore<?, ?> store = cacheStore();

    if (store != null) {
      cfg.setCacheStoreFactory(new TestStoreFactory());
      cfg.setReadThrough(true);
      cfg.setWriteThrough(true);
      cfg.setLoadPreviousValue(true);
    }

    cfg.setSwapEnabled(swapEnabled());
    cfg.setCacheMode(cacheMode());
    cfg.setAtomicityMode(atomicityMode());
    cfg.setWriteSynchronizationMode(writeSynchronization());
    cfg.setNearConfiguration(nearConfiguration());

    Class<?>[] idxTypes = indexedTypes();

    if (!F.isEmpty(idxTypes)) cfg.setIndexedTypes(idxTypes);

    if (cacheMode() == PARTITIONED) cfg.setBackups(1);

    return cfg;
  }
  /** {@inheritDoc} */
  @SuppressWarnings("unchecked")
  @Override
  protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
    IgniteConfiguration c = super.getConfiguration(gridName);

    TransactionConfiguration txCfg = c.getTransactionConfiguration();

    txCfg.setDefaultTxConcurrency(txConcurrency);
    txCfg.setDefaultTxIsolation(txIsolation);
    txCfg.setTxSerializableEnabled(true);

    CacheConfiguration cc = defaultCacheConfiguration();

    cc.setCacheMode(cacheMode());
    cc.setAtomicityMode(TRANSACTIONAL);

    cc.setSwapEnabled(false);

    cc.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);

    cc.setEvictionPolicy(plc);
    cc.setEvictSynchronizedKeyBufferSize(1);

    cc.setEvictSynchronized(true);

    if (testStore != null) {
      cc.setCacheStoreFactory(singletonFactory(testStore));
      cc.setReadThrough(true);
      cc.setWriteThrough(true);
      cc.setLoadPreviousValue(true);
    } else cc.setCacheStoreFactory(null);

    c.setCacheConfiguration(cc);

    TcpDiscoverySpi disco = new TcpDiscoverySpi();

    disco.setIpFinder(ipFinder);

    c.setDiscoverySpi(disco);

    return c;
  }
  /**
   * Executes example.
   *
   * @param args Command line arguments, none required.
   * @throws IgniteException If example execution failed.
   */
  public static void main(String[] args) throws IgniteException {
    ExamplesUtils.checkMinMemory(MIN_MEMORY);

    // To start ignite with desired configuration uncomment the appropriate line.
    try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {
      System.out.println();
      System.out.println(">>> Cache store example started.");

      CacheConfiguration<Long, Person> cacheCfg = new CacheConfiguration<>(CACHE_NAME);

      // Set atomicity as transaction, since we are showing transactions in example.
      cacheCfg.setAtomicityMode(TRANSACTIONAL);

      // Configure JDBC store.
      cacheCfg.setCacheStoreFactory(FactoryBuilder.factoryOf(CacheJdbcPersonStore.class));

      // Configure JDBC session listener.
      cacheCfg.setCacheStoreSessionListenerFactories(
          new Factory<CacheStoreSessionListener>() {
            @Override
            public CacheStoreSessionListener create() {
              CacheJdbcStoreSessionListener lsnr = new CacheJdbcStoreSessionListener();

              lsnr.setDataSource(CacheJdbcPersonStore.DATA_SRC);

              return lsnr;
            }
          });

      cacheCfg.setReadThrough(true);
      cacheCfg.setWriteThrough(true);

      try (IgniteCache<Long, Person> cache = ignite.getOrCreateCache(cacheCfg)) {
        // Make initial cache loading from persistent store. This is a
        // distributed operation and will call CacheStore.loadCache(...)
        // method on all nodes in topology.
        loadCache(cache);

        // Start transaction and execute several cache operations with
        // read/write-through to persistent store.
        executeTransaction(cache);
      }
    }
  }