Update Existing 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
- Include the following namespace in your application:
Alachisoft.NCache.Client
Alachisoft.NCache.Runtime.Exceptions
- 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 Custom Object
You can update a single object in the cache using various overloads of the Insert() method. This returns CacheItemVersion. For Java, Insert() method is used to update a single object in the cache.
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)
{
// Exception can occur due to:
// Connection Failures
// Operation Timeout
// Operation performed during state transfer
}
catch (Exception ex)
{
// Any generic exception like ArgumentNullException or ArgumentException
}
Single Cache Item
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. For Java, Insert() method is used to update single CacheItem in the cache.
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
var cacheItem = new CacheItem(product);
// cacheItem.AbsoluteExpiration = DateTime.Now.AddMinutes(5);
// Insert updated CacheItem to cache
CacheItemVersion version = cache.Insert(key, cacheItem);
}
catch (OperationFailedException ex)
{
// Exception can occur due to:
// Connection Failures
// Operation Timeout
// Operation performed during state transfer
}
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. For Java, insertBulk() is used to update an array of CacheItem.
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();
//Create a dictionary to add CacheItems
IDictionary<string, CacheItem> dictionary = new Dictionary<string, CacheItem>();
foreach (var prod in products)
{
string key = $"Product:{prod.ProductID}";
var cacheItem = new CacheItem(prod);
//Add dictionary to cache
dictionary.Add(key, cacheItem);
}
//Returning failed to update items
IDictionary<string, Exception> keysFailedToUpdate = cache.InsertBulk(dictionary);
if (keysFailedToAdd.Count > 0)
{
foreach (KeyValuePair<string, Exception> entry in keysFailedToAdd)
{
// Check failure reason
if (entry.Value is OperationFailedException)
{
var ex = entry.Value as OperationFailedException;
if(ex.ErrorCode == NCacheErrorCodes.KEY_ALREADY_EXISTS)
{
// The specified key already exists in cache,
// Either remove the existing object from cache
// Or specify another key
}
}
else
{
// Any other exception
}
}
}
catch (OperationFailedException ex)
{
// Exception can occur due to:
// Connection Failures
// Operation Timeout
// Operation performed during state transfer
}
catch (Exception ex)
{
// Any generic exception like ArgumentNullException or ArgumentException
}
Asynchronous API
Note
This feature is only available in NCache Enterprise Edition.
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 list of actions to be performed on the cache is maintained in a queue at the client side and a dedicated background thread keeps on sending them to the server side. Hence, all the operations are being executed in a pure asynchronous manner, increasing the efficiency of the client application.
InsertAsync returns object of the Task class which can further be used according to the business needs of the client application. NCache provides three different status flags to notify the success or failure of the operation. For Java, InsertAsync() is used for this purpose.
IsCanceled: Notifies if the InsertAsync function is canceled.
IsCompleted: Notifies if the InsertAsync function is completed.
IsFaulted: Notifies if the InsertAsync function is faulted.
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}";
// Add Product object to cache
Task task = cache.InsertAsync(key, product)
//This task object can be used as per your business needs
if (task.IsFaulted)
{
// Task completed due to an unhandled exception
}
}
catch (OperationFailedException ex)
{
// NCache specific exception
// Exception can occur due to Connection Failure
}
catch (Exception ex)
{
// Any generic exception like ArgumentNullException or ArgumentException
}
Recommendation: To ensure the operation is fail safe, it is recommended to handle any potential exceptions within your application, as explained in Handling Failures.
JsonObject
Note
This feature is only available in NCache Enterprise Edition.
You can update a pre-existing Json data in the cache using Insert. Using this method any Json data is added in the cache if no such value exists and the previous value is updated if the object already exists. For more detail on the topic, please refer to the Cache Data as JSON section.
Note
In order to use JsonValueBase
, please add the following namespace in your application:
Alachisoft.NCache.Runtime.JSON
The following example updates the value of a pre-existing JsonObject
in the cache using the Insert method.
try
{
// Pre-Condition: Cache is already connected
// Cache is JSON serialized
// Get product from database against given product ID
Product product = FetchProductFromDB(1001);
// Create a unique key for the object
string key = $"Product:{product.ProductID}";
// Create a new JSON object and set attributes
// string values need to be added with JsonValue
var jsonProduct = new JsonObject();
jsonProduct.AddAttribute("ProductID", product.ProductID);
jsonProduct.AddAttribute("ProductName", (JsonValue)product.ProductName);
jsonProduct.AddAttribute("Category", (JsonValue)product.Category);
jsonProduct.AddAttribute("UnitPrice", product.UnitPrice);
jsonProduct.AddAttribute("UnitsInStock", product.UnitsInStock);
// Add object in the cache with the key
cache.Insert(key, jsonProduct);
// JsonObject will successfully be added to the cache
}
catch (OperationFailedException ex)
{
if (ex.ErrorCode == NCacheErrorCodes.ATTRIBUTE_ALREADY_EXISTS)
{
// An attribute already exists with the same name
}
else if (ex.ErrorCode == NCacheErrorCodes.REFERENCE_TO_SELF)
{
// No object can contain a reference to itself
}
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
}
Additional Resources
NCache provides sample application for Basic Operations at:
- GitHub
- Shipped with NCache: %NCHOME%\samples\dotnet\BasicOperations
See Also
Connecting to Cache
Add Data to Cache
Retrieve Existing Cache Data
Remove Data from Cache
Create Cache