Update Data in Cache
Once data is added to the cache for the first time, you can update its contents against the existing key(s). This means that for the added key, you can overwrite the value existing in cache. This is useful if you cache data which needs to be refreshed periodically.
NCache provides the Insert() method and its overloads to facilitate updating objects in the cache. While it overwrites data for existing items, it also adds the item to cache if the key does not exist in cache.
For example, an e-commerce site needs to update the unit availability of each product in the cache at the end of each business day. This means that the value of the products already existing in cache will be updated against the same key. Moreover, there are also some new products which do not exist in the cache, Insert() will add these products to the cache for the first time as well. This is a more flexible approach compared to Add(), which supports one-time addition of the item.
Insert Operation Behavior
Data can be updated in NCache either as a single item, bulk of items or asynchronously.
Insert will overwrite existing cache item(s) with the same key(s). If the key does not exist, the operation adds the item to the cache instead.
Insert returns CacheItemVersion, a value which internally marks the version of the cache item being updated. For each subsequent update of the same item, this version will be updated. This is used in data concurrency scenarios to internally keep track of the updated objects, and is discussed in detail in the chapter Optimistic Locking.
In advanced cases, if data source is configured, data will be updated in the cache as well as the data source. For more details, refer to the chapter Data Source Providers.
Pre-requisites For Updating Data
- Include the following namespace in your application:
Alachisoft.NCache.Web.Caching
. - The application must be connected to cache before performing the operation.
- Cache must be running.
- Make sure that the data being updated 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.
Single Item
You can update a single object in the cache using various overloads of the Insert() method. This returns CacheItemVersion.
Important
- If the key already exists, it will overwrite existing cache item with the same key.
- If the key does not exist, the operation adds the item to the cache instead.
Recommendation: To ensure the operation is fail safe, it is recommended to handle any potential exceptions within your application, as explained in Handling Failures.
The following example gets updated values of an existing object and inserts it against the same key into the cache. If the key does not exist, it adds it to the cache.
try
{
// Pre-condition: Cache is already connected
// Get updated product from database against given product ID
Product product = FetchProductFromDB(1001);
// Cache key remains the same for this product
string key = $"Product:{product.ProductID}";
// Insert Product object to cache
CacheItemVersion version = cache.Insert(key, product);
// Item updated in cache successfully
}
catch (OperationFailedException ex)
{
// NCache specific exception can occur due to:
// Connection failures
// Operation performed during state transfer
// Operation timeout
}
catch (Exception ex)
{
// Any generic exception like ArgumentNullException or ArgumentException
}
CacheItem
CacheItem is a custom class provided by NCache which can be used to add data to the cache and also lets you set additional specifications associated with an object as properties of this class. The CacheItem is updated in the cache against a unique key.
Important
- If the key already exists, it will overwrite the existing cache item with the same key.
- If the key does not exist, the operation adds the item to the cache instead.
Recommendation: To ensure the operation is fail safe, it is recommended to handle any potential exceptions within your application, as explained in Handling Failures.
The following example gets updated values of an existing CacheItem and inserts it against the same key into the cache. If the key does not exist, it adds it to the cache.
try
{
// Pre-condition: Cache is already connected
// Get updated product from database against given product ID
Product product = FetchProductFromDB(1001);
// Using the same key for the product
string key = $"Product:{product.ProductID}";
// Create a new CacheItem for this product
// You can OPTIONALLY specify multiple properties e.g. Priority, Expiration
// These properties are explained in successive chapters
CacheItem cacheItem = new CacheItem(product);
// cacheItem.AbsoluteExpiration = DateTime.Now.AddMinutes(5);
// Insert updated CacheItem to cache
CacheItemVersion version = cache.Insert(key, cacheItem);
}
catch (OperationFailedException ex)
{
// NCache specific exception can occur due to:
// Connection failures
// Operation performed during state transfer
// Operation timeout
}
catch (Exception ex)
{
// Any generic exception like ArgumentNullException or ArgumentException
}
Bulk Items
NCache also allows synchronous bulk updating of items in a single call to reduce network cost. InsertBulk() updates an array of CacheItem
to the cache for its existing corresponding cache keys. The method returns a dictionary of all the keys that fail to update, along with the failure reason.
Important
- If the keys already exist, it will overwrite the existing cache item(s) with the same key(s).
- If the key does not exist, the operation adds the item to the cache instead.
Note
Any keys that fail to update and their failure reason will be returned as an IDictionary
.
Although a bulk operation is executed as a single operation, the failure of operations is treated individually. For example, if a bulk of 100 items is updated in the cache and due to some issue, 20 items fail to update, the keys of those 20 items will be returned to the application as a dictionary of failed operations along with the failure reason.
Recommendation: To ensure the operation is fail safe, it is recommended to handle any potential exceptions within your application, as explained in Handling Failures.
try
{
// Pre-condition: Cache is already connected
// Fetch all products from database
Product[] products = FetchProductsFromDB();
string[] keys = new string[products.Length];
CacheItem[] cacheItems = new CacheItem[products.Length];
for (int i = 0; i < products.Length; i++)
{
// Using the same unique cache key for this product
keys[i] = $"Product:{products[i].ProductID}";
// Create a new cache item for this product
// You can OPTIONALLY specify multiple properties e.g. Priority, Expiration
// These properties are explained in successive chapters
cacheItems[i] = new CacheItem(products[i]);
// cacheItems[i].AbsoluteExpiration = DateTime.Now.AddMinutes(5);
}
// Insert all products in cache using bulk insert
// Failed keys and failure reason returned in IDictionary
IDictionary keysFailedToAdd = cache.InsertBulk(keys, cacheItems);
// Check if any keys failed to insert
if (keysFailedToAdd.Count > 0)
{
foreach (DictionaryEntry entry in keysFailedToAdd)
{
// Check failure reason
if (entry.Value is OperationFailedException)
{
// NCache specific exception
}
else
{
// Any generic exception like
// ArgumentNullException or ArgumentException
}
}
}
}
catch (OperationFailedException ex)
{
// Exception can occur due to:
// Connection Failure
// Operation performed during state transfer
// Operation Timeout
}
catch (Exception ex)
{
// Any generic exception like ArgumentNullException or ArgumentException
}
Asynchronous API
Asynchronous operations are performed in the background, so the client does not have to wait for the response from the server to execute further operations. The control is returned to the application immediately after performing the operation. This increases overall responsiveness of the application.
Since asynchronous operations do not notify upon the failure or success of the operations themselves, NCache provides a callback mechanism which can be registered while making the operation call. These callbacks are triggered upon success or failure of the operation.
CacheItem
can be updated asynchronously into the cache, with or without callbacks using the InsertAsync() method.
The following example updates a CacheItem
in the cache with its associated unique key. The AsyncItemUpdatedCallback
function is used to register a callback to perform appropriate functions upon completion of the add operation. If the callback is not specified, the data will be updated without callback, using the same API.
Important
Note that this API also allows specifying additional parameters for Data Source Providers and Groups, so the values for those parameters have been passed as None
and null
respectively, as they are not discussed here.
Recommendation: To ensure the operation is fail safe, it is recommended to handle any potential exceptions within your application, as explained in Handling Failures.
// NOTE: If you are using callbacks, include:
using Alachisoft.NCache.Caching;
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}";
// Create a new CacheItem for this product
// You can OPTIONALLY specify multiple properties e.g. Priority, Expiration
// These properties are explained in successive chapters
CacheItem cacheItem = new CacheItem(product);
// cacheItem.AbsoluteExpiration = DateTime.Now.AddMinutes(5);
// Specify AsyncItemUpdatedCallback
// If NOT specified, data will be asynchronously added WITHOUT callback
cacheItem.AsyncItemUpdateCallback += new AsyncItemUpdatedCallback(OnItemAdded);
// Insert data asynchronously
cache.InsertAsync(key, cacheItem, DSWriteOption.None, null);
}
catch (OperationFailedException ex)
{
// NCache specific exception
// Exception can occur due to Connection Failure
}
catch (Exception ex)
{
// Any generic exception like ArgumentNullException or ArgumentException
}
...
// Create a callback method
public static void OnItemUpdated(string key, object status)
{
if (status is Exception ex)
{
// Exception can occur due to:
// Operation performed during state transfer
}
else
{
AsyncOpResult result = (AsyncOpResult)status;
if (result == AsyncOpResult.Success)
{
// Object updated in cache successfully
}
}
}
See Also
Connecting to Cache
Add Data to Cache
Retrieve Data from Cache
Remove Data from Cache
Create Cache