databasetransactionsballerinaballerina-swan-lake

How to rollback a cache insert operation when a transaction fails in Ballerina


I'm currently working on a project where the database layer is backed by a cache system. The requirement is to update both the database and the cache when a new entry is created. I've decided to use Ballerina transactions to achieve this, but I'm facing some challenges.

Specifically, when an error occurs during the transaction, data inconsistency arises. Although changes in the database are effectively reverted during the rollback, the corresponding cache entry remains unchanged.

transaction {
    _ = check createRole(roleName);
    _ = check ketoWriteEP->createRelationTuple(payload);
    check commit;
}

function createRole(string roleName) {
    sql:ParameterizedQuery insertQuery = createAppRoleQuery(roleName, 
        appId, organizationId);
    sql:ExecutionResult result = check dbClient->execute(insertQuery);
    utils:RoleDO role = {role_name: roleName};
    error? response = localcache:addRoleToCache(roleName);
}

How can I address this issue and ensure consistency between the database and cache when using Ballerina transactions?


Solution

  • This can be achieved in a couple of ways,

    1. A rollback handler can be registered, as explained in here.

      This allows the implementation of a custom function to revert the Cache changes, and the function can be registered to be triggered when the rollback is initiated. (Note: Rollback handlers and Commit Handlers are registered only for that particular transaction block)

    2. The cache can be manually rolled back in the on fail block as shown below:

    transaction {
        _ = check createRole(roleName);
        _ = check ketoWriteEP->createRelationTuple(payload);
        check commit;
    } on fail error e {
        // Check weather the error is due to client invocation
        if e !is sql:Error {
            // Remove value from the cache
        }
    }