Configuring WriteThru Provider
To use Write-through caching, you need to implement the IWriteThruProvider
interface provided by NCache. NCache framework will use this custom
implementation to write data on the back-end data source. Please refer to
Configuring Write-through in Administrators' Guide for more details.
Note that if a read-through provider is specified in client.ncconf in the default-writethru-provider
tag, and has also been specified through API, the provider in API will overwrite the one specified in client.ncconf.
IWriteThruProvider Interface
Member | Description |
---|---|
Init |
This method will be called by NCache on cache startup. User can use this method for performing tasks like allocating resources, acquiring connections of data source etc. This method takes as input the HashMap instance of arguments passed to the provider through NCache Manager (configuration settings). It allows you to pass a list of parameters to the provider. These parameters can be utilized in many ways. For example, connection string of a data source can be specified as a parameter. Thus, it provides a flexible way to change the data source settings while configuring it without any code changes. The other argument CacheId specifies the cache name for which write-through is configured. |
WriteToDataSource |
This method will be called by NCache to perform an actual write operation on a configured data source. -For write-through, an atomic operation with write-through will correspond to an atomic -For write-Behind, NCache will call the atomic |
Dispose |
This method will be called by NCache when the cache stops. You can use this method for performing tasks like releasing resources, disposing connections etc. Here you can free the resources related to data sources for effective resource utilization. |
OperationResult
holds information about:
WriteOperation
: Operation performed on data source. UpdateInCache
: This flag specifies whether to update the returned write operation in cache or not. This is only applicable for Add and Insert operation types. In NCache an operation is first applied on cache store and then to data source (if write through caching is enabled). So if user wants to synchronize the cache store after updating data source then this flag will be used.Status
: Write through caching basically synchronizes your data source with cache store. Previously in case of operation failure on data source, item was also removed from cache, now NCache provides more flexible ways to allow user to decide whether to keep the item in cache based on these operation statuses. Success
: This means item was successfully added to the data source so keep it in the cache as well. Failure
: This means item could not be added to data source, so in case of Add/Insert operations, item will be removed from cache. Operation failure exception will be thrown to user in case of Write-Through and logged in case of write behind. FailureDontRemove
: This means item could not be added to the data source, but keep it in the cache. Operation failure exception will be thrown to user in case of write thru and logged in case of write behind. FailureRetry
: This means item could not be added to the data source, keep the item in cache and retry. In case of write thru retry will be performed as write behind operation. While implementing this method, you should take care of code thread safety as multiple requests can access
Note
In NCache, write-through providers are configured on cache level i.e. for clustered caches all nodes will contain provider configurations and their deployed assemblies.
Sample Implementation of IWriteThruProvider Interface
To utilize the
IWriteThruProvider
, include the following namespace in your application:Alachisoft.NCache.Runtime.DatasourceProviders.
After implementing and deploying this provider, you can make direct calls to
NCache for write operations on the data source. NCache will use the
"writeToDataSource
" method in the specified data access class to write
operations on data source.
// Contains methods used to save/update an object to the master data source.
public class SampleWriteThruProvider : IWriteThruProvider
{
// Object used to communicate with the Data source.
private SqlConnection _connection;
//Perform tasks like allocating resources or acquiring connections
public void Init(IDictionary parameters, string cacheId)
{
object connStringObject = parameters["connstring"];
string connString = connStringObject == null ? "" : connStringObject.ToString();
if (connString != ""){
_connection = new SqlConnection(connString);
}
try{
_connection.Open();
}
catch (Exception ex){
//handle exception
}
}
//Perform tasks associated with freeing, releasing, or resetting resources.
public void Dispose()
{
if (_connection != null)
_connection.Close();
}
//Responsible for write operations on data source
public OperationResult WriteToDataSource(WriteOperation operation)
{
Product product = (Product)operation.ProviderCacheItem.Value;
SqlCommand command = new SqlCommand();
command.Connection = _connection;
if (operation.OperationType == WriteOperationType.Add){
command.CommandText = "INSERT INTO Products(ID,Name)VALUES( '" + operation.Key + "','" + product.ProductName + "')";
}
if (operation.OperationType == WriteOperationType.Delete){
command.CommandText = "DELETE FROM Products WHERE ID ='" + operation.Key + "'";
}
if (operation.OperationType == WriteOperationType.Update){
command.CommandText = "UPDATE Products SET Name = '" + product.ProductName + "' WHERE ID='" + operation.Key + "'";
}
int result = command.ExecuteNonQuery();
OperationResult operationResult = new OperationResult(operation, OperationResult.Status.Success);
if (result < 1){
operationResult.DSOperationStatus = OperationResult.Status.Failure;
}
return operationResult;
}
public OperationResult[] WriteToDataSource(WriteOperation[] operations)
{
OperationResult[] operationResult = new OperationResult[operations.Length];
SqlCommand command = new SqlCommand();
command.Connection = _connection;
int counter = 0;
foreach (WriteOperation operation in operations){
Product product = (Product)operation.ProviderCacheItem.Value;
if (operation.OperationType == WriteOperationType.Add){
command.CommandText = "INSERT INTO Products(ID,Name)VALUES( '" + operation.Key + "','" + product.ProductName + "')";
}
if (operation.OperationType == WriteOperationType.Delete){
command.CommandText = "DELETE FROM Products WHERE ID ='" + operation.Key + "'";
}
if (operation.OperationType == WriteOperationType.Update){
command.CommandText = "UPDATE Products SET Name = '" + product.ProductName + "' WHERE ID='" + operation.Key + "'";
}
int result = command.ExecuteNonQuery();
operationResult[counter] = new OperationResult(operation, OperationResult.Status.Success);
if (result < 1){
operationResult[counter].DSOperationStatus = OperationResult.Status.Failure;
}
counter++;
}
return operationResult;
}
}
See Also
Using Write-Through with Basic Operations
Using Write-Behind with Basic Operations