• Webinars
  • Docs
  • Download
  • Blogs
  • Contact Us
Try Free
Show / Hide Table of Contents

Read-Through Usage with Cache Operation

Note

This feature is only available in NCache Enterprise Edition.

This section explains the use of Read-Through provider after configuring and deploying it. NCache provides Alachisoft.NCache.Runtime.Caching.ReadThruOptions class to specify ReadThru options in APIs. ReadThruOptions class contains enum ReadMode which can either be ReadThru or ReadThruForced explained below.

  1. ReadThru checks for existence of an item in cache and if not found, fetches the data from the data source.
  2. ReadThruForced fetches the item from data source regardless of its existence in the cache or not.

Multiple Read-Through providers can be configured through NCache. Default Read-Through provider will be called if specific provider name is not mentioned through API. You can also use providers other than default by using provider specific overloads of APIs.

Important

For Java, before deploying your JAR files, you need to make sure that:

  • JDK 11 is installed.
  • Environment variable for Java is set.

Prerequisites

  • .NET/.NET Core
  • Java
  • Install the following NuGet package in your application:
    • Enterprise: Alachisoft.NCache.SDK
  • To utilize the APIs, include the following namespace in your application:
    • Alachisoft.NCache.Runtime.DatasourceProviders
    • Alachisoft.NCache.Runtime.Caching
    • Alachisoft.NCache.Client
    • Alachisoft.NCache.Runtime.Exceptions
  • Cache must be running.
  • The application must be connected to cache before performing the operation.
  • Make sure that the data being added is serializable.
  • For API details refer to: CacheItem, Get, ReadMode, GetBulk , CacheConnectionOptions.
  • To ensure the operation is fail safe, it is recommended to handle any potential exceptions within your application, as explained in Handling Failures.
  • To handle any unseen exceptions, refer to the Troubleshooting section.
  • Add the following Maven dependencies in your pom.xml file:
<dependency>
    <groupId>com.alachisoft.ncache</groupId>
    <artifactId>ncache-client</artifactId>
    <version>x.x.x</version>
</dependency>
  • Import the following packages in your application:
    • import com.alachisoft.ncache.client.*
    • import com.alachisoft.ncache.runtime.exceptions.*
    • import com.alachisoft.ncache.runtime.datasourceprovider.*
  • Cache must be running.
  • The application must be connected to cache before performing the operation.
  • For API details refer to: CacheItem , get, getBulk.
  • Make sure that the data being added is serializable.
  • To ensure the operation is fail safe, it is recommended to handle any potential exceptions within your application, as explained in Handling Failures.
  • To handle any unseen exceptions, refer to the Troubleshooting section.

Using Read-Through with Get Operation

The following example retrieves an item with Read-Through enabled, corresponding to the specified key using the Get method.

  • .NET/.NET Core
  • Java
try
{
  // Pre-condition: Cache is already connected

  // Specify the key of the item
  string key = $"Product:{product.ProductID}";

  // Specify the readThruOptions for read through operations
  var readThruOptions = new ReadThruOptions();
  readThruOptions.Mode = ReadMode.ReadThru;

  // Retrieve the data of the corresponding item with read thru enabled
  Product data = cache.Get<Product>(key, readThruOptions);

  if (data != null)
  {
    // Perform operations accordingly
  }
}
catch (OperationFailedException ex)
{
  if (ex.ErrorCode == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE)
  {
    // Backing source is not available
  }
  else
  {
    // Exception can occur due to:
    // Connection Failures
    // Operation Timeout
    // Operation performed during state transfer
  }
}
catch (Exception ex)
{
  // Any generic exception like ArgumentNullException or ArgumentException
}
try {
  // Pre-condition: Cache is already connected
  // Specify the key of the item
  String key = "Product:" + product.getProductID();

  // Specify the readThruOptions for read through operations
  var readThruOptions = new ReadThruOptions(ReadMode.ReadThru);
  readThruOptions.setReadMode(ReadMode.ReadThru);

  // Retrieve the data of the corresponding item with read thru enabled
  Product data = cache.get(key,readThruOptions,Product.class);

  if (data != null) {
    // Perform operations accordingly
  }
} catch (OperationFailedException ex) {
  if (ex.getErrorCode() == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE) {
    // Backing source is not available
  } else {
    // Exception can occur due to:
    // Connection Failures
    // Operation Timeout
    // Operation performed during state transfer
  }
} catch (Exception ex) {
  // Any generic exception like NullPointerException or IllegalArgumentException
}

Using ForcedRead-Through

NCache provides an option of forced Read-Through, through which NCache fetches the data from data source forcefully. It means that the data will not be checked in the cache and will directly be fetched from the data source. You can enable forced Read-Through by specifying the ReadMode as ReadThruForced.

The following example gets an item from the cache using the ReadThruForced option by forcefully enabling Read-Through on it.

  • .NET/.NET Core
  • Java
try
{
  // Pre-condition: Cache is already connected

  // Specify the key of the item
  string key = $"Product:{product.ProductID}";

  // Specify the readThruOptions for read through operations
  var readThruOptions = new ReadThruOptions();
  readThruOptions.Mode = ReadMode.ReadThruForced;

  // Retrieve the data of the corresponding item with read thru enabled
  Product data = cache.Get<Product>(key, readThruOptions);

  if (data != null)
  {
    // Perform operations accordingly
  }
}
catch (OperationFailedException ex)
{
  if (ex.ErrorCode == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE)
  {
    // Backing source is not available
  }
  else
  {
    // Exception can occur due to:
    // Connection Failures
    // Operation Timeout
    // Operation performed during state transfer
  }
}
catch (Exception ex)
{
  // Any generic exception like ArgumentNullException or ArgumentException
}
try {
  // Pre-condition: Cache is already connected

  // Specify the key of the item
  String key = "Product:" + product.getProductID();

  // Specify the readThruOptions for read through operations
  var readThruOptions = new ReadThruOptions(ReadMode.ReadThruForced);
  readThruOptions.setReadMode(ReadMode.ReadThruForced);

  // Retrieve the data of the corresponding item with read thru enabled
  Product data = cache.get(key,readThruOptions,Product.class);

  if (data != null) {
    // Perform operations accordingly
  }
} catch (OperationFailedException ex) {
  if (ex.getErrorCode() == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE) {
    // Backing source is not available
  } else {
    // Exception can occur due to:
    // Connection Failures
    // Operation Timeout
    // Operation performed during state transfer
  }
} catch (Exception ex) {
  // Any generic exception like NullPointerException or IllegalArgumentException
}

Using Read-Through with Bulk Operations

The following example retrieves a dictionary of products with Read-Through enabled, corresponding to the specified keys using the GetBulk method.

Tip

For better understanding of the these operations review Bulk Operations.

  • .NET/.NET Core
  • Java
try
{
  // Pre-Condition: Cache is already connected

  // Create a new array of keys 
  String[] keys = new string[];

  // Specify the readThruOptions for read through operations
  var readThruOptions = new ReadThruOptions();
  readThruOptions.Mode = ReadMode.ReadThru;

  // Retrieve the dictionary of Products with corresponding products
  IDictionary<string, Product> retrievedItems = cache.GetBulk<Product>(keys, readThruOptions);

  // IDictionary contains cached keys and values
}
catch (OperationFailedException ex)
{
  if (ex.ErrorCode == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE)
  {
    // Backing source is not available
  }
  else
  {
    // Exception can occur due to:
    // Connection Failures
    // Operation Timeout
    // Operation performed during state transfer
  }
}
catch (Exception ex)
{
  // Any generic exception like ArgumentNullException or ArgumentException
}
try {
  // Pre-Condition: Cache is already connected

  // Create a new array of keys
  List<String> keys = new ArrayList<>();

  // Specify the readThruOptions for read through operations
  var readThruOptions = new ReadThruOptions(ReadMode.ReadThru);
  readThruOptions.setReadMode(ReadMode.ReadThru);

  // Retrieve the dictionary of Products using Map with corresponding products
  Map<String, Product> retrievedItems = cache.getBulk(keys,readThruOptions,Product.class);
} catch (OperationFailedException ex) {
  if (ex.getErrorCode() == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE) {
    // Backing source is not available
  } else {
    // Exception can occur due to:
    // Connection Failures
    // Operation Timeout
    // Operation performed during state transfer
  }
} catch (Exception ex) {
  // Any generic exception like NullPointerException or IllegalArgumentException
}

Using Read-Through with CacheItem

The following example retrieves a CacheItem with Read-Through enabled, corresponding to the specified key.

  • .NET/.NET Core
  • Java
try
{
  // Pre-condition: Cache is already connected

  // Specify the key of the item
  string key = $"Product:{product.ProductID}";

  // Specify the readThruOptions for read through operations
  var readThruOptions = new ReadThruOptions();
  readThruOptions.Mode = ReadMode.ReadThru;

  // Retrieve the data of the corresponding item with read thru enabled
  CacheItem data = cache.GetCacheItem(key, readThruOptions);

  if (data != null)
  {
    // Perform operations accordingly
  }
}
catch (OperationFailedException ex)
{
  if (ex.ErrorCode == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE)
  {
    // Backing source is not available
  }
  else
  {
    // Exception can occur due to:
    // Connection Failures
    // Operation Timeout
    // Operation performed during state transfer
  }
}
catch (Exception ex)
{
  // Any generic exception like ArgumentNullException or ArgumentException
}
try {
  // Pre-condition: Cache is already connected

  // Specify the key of the item
  String key = "Product" + product.getProductID();

  // Specify the readThruOptions for read through operations
  var readThruOptions = new ReadThruOptions(ReadMode.ReadThru);
  readThruOptions.setReadMode(ReadMode.ReadThru);

  // Retrieve the data of the corresponding item with read thru enabled
  CacheItem data = cache.getCacheItem(key,readThruOptions);

  if(data != null) {
    // Perform operations accordingly
  }
} catch (OperationFailedException ex) {
  if (ex.getErrorCode() == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE) {
    // Backing source is not available
  } else {
    // Exception can occur due to:
    // Connection Failures
    // Operation Timeout
    // Operation performed during state transfer
  }
} catch (Exception ex) {
  // Any generic exception like NullPointerException or IllegalArgumentException
}

Using Read-Through with Data Structures

The following example retrieves a Counter, List, Queue, HashSet and Dictionary with Read-Through enabled, corresponding to the specified key.

  • .NET/.NET Core
  • Java
try
{
  // Pre-condition: Cache is already connected

  // Specify the key of the item
  string key = $"Product:{product.ProductID}";

  // Specify the readThruOptions for read through operations
  var readThruOptions = new ReadThruOptions();
  readThruOptions.Mode = ReadMode.ReadThru;

  switch(mainMenu) 
  {
    case mainMenu.GetDistributedCounter:
      // Retrieve the count of the corresponding item with read thru enabled
      ICounter counter = cache.DataTypeManager.GetCounter(key, readThruOptions);
      break; 
    case mainMenu.GetDistributedDictionary:
      // Retrieve dictionary of the corresponding item with read thru enabled
      IDistributedDictionary<string, object> distributedDictionary = cache.DataTypeManager.GetDictionary<string, object>(key,readThruOptions);
      break;
    case mainMenu.GetDistributedList:
      // Retrieve the list of the corresponding item with read thru enabled
      IDistributedList<object> distributedList = cache.DataTypeManager.GetList<object>(key, readThruOptions);
      break;
    case mainMenu.GetDistributedQueue:
      // Retrieve the queue of the corresponding item with read thru enabled
      IDistributedQueue<object> distributedQueue = cache.DataTypeManager.GetQueue<object>(key, readThruOptions);
      break;
    case mainMenu.GetDistributedHashSet:
      // Retrieve the HashSet of the corresponding item with read thru enabled
      IDistributedHashSet<int> distributedHashSet = cache.DataTypeManager.GetHashSet<int>(key, readThruOptions);
      break;
  }  
}
catch (OperationFailedException ex)
{
  if (ex.ErrorCode == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE)
  {
    // Backing source is not available
  }
  else
  {
    // Exception can occur due to:
    // Connection Failures
    // Operation Timeout
    // Operation performed during state transfer
  }
}
catch (Exception ex)
{
  // Any generic exception like ArgumentNullException or ArgumentException
}
try {
  // Pre-condition: Cache is already connected

  // Specify the key of the item
  String key = "Product:" + product.getProductID();

  // Specify the readThruOptions for read through operations
  var readThruOptions = new ReadThruOptions(ReadMode.ReadThru);
  readThruOptions.setReadMode(ReadMode.ReadThru);

  switch(mainMenu) {
    case GetDistributedCounter:
      // Retrieve the count of the corresponding item with read thru enabled
      Counter counter = cache.getDataStructuresManager().getCounter(key, readThruOptions);
      break; 
    case GetDistributedDictionary:
      // Retrieve dictionary of the corresponding item with read thru enabled
      DistributedDictionary distributedDictionary = cache.getDataStructuresManager().getMap(key,readThruOptions);
      break;
    case GetDistributedList:
      // Retrieve the list of the corresponding item with read thru enabled
      DistributedList distributedList = cache.getDataStructuresManager().getList(key, readThruOptions);
      break;
    case GetDistributedQueue:
      // Retrieve the queue of the corresponding item with read thru enabled
      DistributedQueue distributedQueue = cache.getDataStructuresManager().getQueue(key, readThruOptions);
      break;
    case GetDistributedHashSet:
      // Retrieve the HashSet of the corresponding item with read thru enabled
      DistributedHashSet distributedHashSet = cache.getDataStructuresManager().getHashSet(key, readThruOptions);
      break;
  } 
} catch (OperationFailedException ex) {
  if (ex.getErrorCode() == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE) {
    // Backing source is not available
  } else {
    // Exception can occur due to:
    // Connection Failures
    // Operation Timeout
    // Operation performed during state transfer
  }
} catch (Exception ex) {
  // Any generic exception like NullPointerException or IllegalArgumentException
}

Configure Default Read-Through Provider

You can specify the default provider through NCache Web Manager or through client.ncconf file placed in the config folder of the NCache installation directory. If the provider name is not provided in both the API and client.ncconf, then default provider will automatically be used.

<cacheid="mycache" default-readthru-provider="defaultProviderName" client-cache-id="" client-cache-syncmode="optimistic" default-writethru-provider="" load-balance="True">
  ...
</cache>

CacheConnectionOptions can also be used to specify providers. NCache provides errors in cache logs in case of an exception during loading the provided assemblies.

Additional Resources

NCache provides sample application for Read-Through on GitHub.

See Also

Implement Read-Through Provider
Read-Through Provider Configuration and Implementation
Write-Through Caching
Cache Startup Loader and Refresher
Custom Cache Dependencies

Back to top Copyright © 2017 Alachisoft