Using Write-Behind with Cache Operations
Note
This feature is only available in NCache Enterprise Edition.
Important
For Java, before deploying your JAR files, you need to make sure that:
- You have JDK 11 installed.
- Your Environment Variable for Java is set.
Pre-Requisites for Using WriteThrough
- Install the following NuGet package in your application.
- To utilize the APIs, include the following namespaces in your application:
Alachisoft.NCache.Runtime.DatasourceProviders
Alachisoft.NCache.Runtime.Caching
Alachisoft.NCache.Client
Alachisoft.NCache.Runtime.Exceptions
- The application must be connected to cache before performing the operation.
- Cache must be running.
- For API details refer to: CacheItem, Get, Insert(), IWriteThruProvider, Remove, InsertBulk(), RemoveBulk(), InsertAsync(), RemoveAsync()
- 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/Update with Write-Behind
You can add/update CacheItems in the cache with write-behind enabled with or without Callback. Adding with callback notifies you on the type of event occurred which you register.
Add without Callback Method
The following example adds an item in the cache with write-behind enabled using the Insert()
method. Using this method, if an item is already present in the cache, the new value overwrites the old value.
try
{
// Pre-Condition: Cache is already connected
// Specify the key of the cacheItem
Product product = FetchProductByProductID(1001);
string key = $"product:ProductID";
var cacheItem = new CacheItem(product);
// Enable write through for the cacheItem created
var writeThruOptions = new WriteThruOptions();
writeThruOptions.Mode = WriteMode.WriteBehind;
// Add item in the cache with write-behind
cache.Insert(key, cacheItem, writeThruOptions);
}
catch (OperationFailedException ex)
{
if (ex.ErrorCode == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE)
{
// Backing source is not available
}
else if (ex.ErrorCode == NCacheErrorCodes.SYNCHRONIZATION_WITH_DATASOURCE_FAILED)
{
// Synchronization of data with backing source is failed
// due to any error
}
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
}
Add with Callback Method
The following example adds an item in the cache with callback registered, with an event type of ItemAdded.
try
{
// Pre-Condition: Cache is already connected
// Specify the key of the cacheItem
Product product = FetchProductByProductID(1001);
string key = $"product:ProductID";
var cacheItem = new CacheItem(product);
// Enable write through for the cacheItem created
var writeThruOptions = new WriteThruOptions();
writeThruOptions.Mode = WriteMode.WriteBehind;
writeThruOptions.SetDataSourceNotification(DataSourceModifiedCallBack, EventType.ItemAdded);
// Add item in the cache with write-behind
cache.Insert(key, cacheItem, writeThruOptions);
}
catch (OperationFailedException ex)
{
if (ex.ErrorCode == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE)
{
// Backing source is not available
}
else if (ex.ErrorCode == NCacheErrorCodes.SYNCHRONIZATION_WITH_DATASOURCE_FAILED)
{
// Synchronization of data with backing source is failed
// due to any error
}
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
}
private void DataSourceModifiedCallBack(string key, WriteBehindOpResult result)
{
// Perform appropriate actions upon response
}
Remove Existing Data with Write-Behind
The following example removes the item from the cache using the Remove
method, corresponding to the key provided as well as from the data source and registers the events for the operation.
try
{
// Pre-Condition: Cache is already connected
// Specify the key of the item
string key = "Product:1001";
// Enable write through for the cacheItem created
var writeThruOptions = new WriteThruOptions();
writeThruOptions.Mode = WriteMode.WriteBehind;
writeThruOptions.SetDataSourceNotification(DataSourceModifiedCallBack, EventType.ItemRemoved);
// Remove the item corresponding to the key with write-through enabled
cache.Remove(key, null, null, writeThruOptions);
}
catch (OperationFailedException ex)
{
if (ex.ErrorCode == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE)
{
// Backing source is not available
}
else if (ex.ErrorCode == NCacheErrorCodes.SYNCHRONIZATION_WITH_DATASOURCE_FAILED)
{
// Synchronization of data with backing source is failed
// due to any error
}
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
}
private void DataSourceModifiedCallBack(string key, WriteBehindOpResult result)
{
// Perform appropriate actions upon response
}
Bulk Operations
Add/Update Bulk Items to the Cache
The following example adds bulk items in the cache with write behind enabled. Using the InsertBulk()
method if the items are already present in the cache, new values overwrite the existing values.
try
{
// Pre-condition: Cache is already connected
// Fetch all products from database
Product[] products = FetchProductsFromDB();
var writeThruOptions = new WriteThruOptions();
writeThruOptions.Mode = WriteMode.WriteBehind;
writeThruOptions.SetDataSourceNotification(DataSourceModifiedCallBack, EventType.ItemAdded);
writeThruOptions.SetDataSourceNotification(DataSourceModifiedCallBack, EventType.ItemUpdated);
IDictionary<string, CacheItem> dictionary = new Dictionary<string, CacheItem>();
foreach(var product in products)
{
string key = $"Product:{product.ProductID}";
var cacheItem = new CacheItem(product);
dictionary.Add(key, cacheItem);
}
IDictionary<string, Exception> keysFailedToUpdate = cache.InsertBulk(dictionary, writeThruOptions);
}
catch (OperationFailedException ex)
{
if (ex.ErrorCode == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE)
{
// Backing source is not available
}
else if (ex.ErrorCode == NCacheErrorCodes.SYNCHRONIZATION_WITH_DATASOURCE_FAILED)
{
// Synchronization of data with backing source is failed
// due to any error
}
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
}
private void DataSourceModifiedCallBack(string key, WriteBehindOpResult result)
{
// Perform appropriate actions upon response
}
Remove Existing Items from Cache
The following example removes a bulk of items from the cache with write behind enabled using the RemoveBulk()
method.
protected void OnDataSourceItemsRemoved(IDictionary iDict)
{
//Perform appropriate actions upon response
}
try
{
// Pre-condition: Cache is already connected
// Get Keys
Product[] products = FetchProductsFromDB();
// Specify keys to remove from cache
string[] keys = new string[products.Length];
int index = 0;
foreach (var product in products)
{
keys[index] = $"Product:{product.ProductID}";
index++;
}
// Create dictionary to store removed items
IDictionary<string, Product> removedItems = new Dictionary<string,Product>();
var writeThruOptions = new WriteThruOptions();
writeThruOptions.Mode = WriteMode.WriteBehind;
writeThruOptions.SetDataSourceNotification(DataSourceModifiedCallBack, EventType.ItemRemoved);
// Remove items with write-behind enabled
cache.RemoveBulk(keys, out removedItems, writeThruOptions);
}
catch (OperationFailedException ex)
{
if (ex.ErrorCode == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE)
{
// Backing source is not available
}
else if (ex.ErrorCode == NCacheErrorCodes.SYNCHRONIZATION_WITH_DATASOURCE_FAILED)
{
// Synchronization of data with backing source is failed
// due to any error
}
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
}
private void DataSourceModifiedCallBack(string key, WriteBehindOpResult result)
{
// Perform appropriate actions upon response
}
Asynchronous Operations
Add/Update Item with Write-Behind
The following example adds item asynchronously in cache using the default provider and Write-Behind option using the InsertAsync() method.
try
{
// Pre-condition: Cache is already connected
// Get product from database against given product ID
Product product = FetchProductFromDB(1001);
// Generate a unique cache key for this product
string key = $"Product:{product.ProductID}";
var cacheItem = new CacheItem(product);
// Enable write behind for the cacheItem created
var writeThruOptions = new WriteThruOptions();
writeThruOptions.Mode = WriteMode.WriteBehind;
writeThruOptions.SetDataSourceNotification(DataSourceModifiedCallBack, EventType.ItemAdded);
// Add Product object to cache
Task task = cache.InsertAsync(key, cacheItem, writeThruOptions);
}
catch (OperationFailedException ex)
{
if (ex.ErrorCode == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE)
{
// Backing source is not available
}
else if (ex.ErrorCode == NCacheErrorCodes.SYNCHRONIZATION_WITH_DATASOURCE_FAILED)
{
// Synchronization of data with backing source is failed
// due to any error
}
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
}
private void DataSourceModifiedCallBack(string key, WriteBehindOpResult result)
{
// Perform appropriate actions upon response
}
Remove Item with Write-Behind
The following example removes existing items asynchronously from the cache using the RemoveAsync() method.
try
{
// Pre-condition: Cache is already connected
// Unique cache key of product to remove
string key = $"Product:{product.ProductID}";
// Enable write behind for the cacheItem created
var writeThruOptions = new WriteThruOptions();
writeThruOptions.Mode = WriteMode.WriteBehind;
writeThruOptions.SetDataSourceNotification(DataSourceModifiedCallBack, EventType.ItemRemoved);
// Asynchronously remove items from cache
Task<Product> task = cache.RemoveAsync<Product>(key, writeThruOptions);
}
catch (OperationFailedException ex)
{
if (ex.ErrorCode == NCacheErrorCodes.BACKING_SOURCE_NOT_AVAILABLE)
{
// Backing source is not available
}
else if (ex.ErrorCode == NCacheErrorCodes.SYNCHRONIZATION_WITH_DATASOURCE_FAILED)
{
// Synchronization of data with backing source is failed
// due to any error
}
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
}
private void DataSourceModifiedCallBack(string key, WriteBehindOpResult result)
{
// Perform appropriate actions upon response
}
Additional Resources
NCache provides sample application for write-behind on GitHub.
See Also
Write-Through Provider Configuration and Implementation
Monitor Write-Through Counters
Configuring Write-Through Provider