我目前正在进行一个项目,其中数据库层由缓存系统提供支持.要求是在创建新条目时同时更新数据库和缓存.我已经决定使用芭蕾舞团交易来实现这一点,但我面临着一些挑战.

具体地说,当事务期间发生错误时,就会出现数据不一致.尽管在回滚期间有效地恢复了数据库中的更改,但相应的缓存条目保持不变.

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);
}

在使用Ballina事务时,如何解决此问题并确保数据库和缓存之间的一致性?

推荐答案

这可以通过几种方式来实现,

  1. 可以注册回滚处理程序,如here中所述.

    这允许自定义函数的实现将 缓存更改,可以注册该函数以触发 启动回滚的时间.(注:回滚处理程序和提交 仅为该特定事务块注册处理程序)

  2. 缓存可以在on fail块中手动回滚,如下图所示:

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
    }
}

Database相关问答推荐

为Postgres数据库字段创建复合索引

如何在保持相同 Flyway 校验和的同时更正语法?

数据库约束 - 保留(keep)还是忽略(ignore)?

这到底是做什么的 Class.forName("com.mysql.jdbc.Driver").newInstance();

repeating groups是什么意思?

Android - SQLite 数据库存储在哪里?

PHP + SQL Server - 如何设置连接字符集?

数据库设计—应该避免一对一的关系吗?

主键、唯一键和外键约束以及索引之间有什么区别?

自动增量唯一标识符

MySQL 数据库中列名中的连字符

在 Rails 中销毁/删除数据库

我可以用 JPA 命名我的约束吗?

Android 上的测试数据库:ProviderTestCase2 还是 RenamingDelegatingContext?

SQL Server 自动备份

何时在关系数据库中使用枚举或小表?

Python中准备好的语句和参数化查询之间的混淆

Django:检测数据库后端

MySQL:为什么使用 VARCHAR(20) 而不是 VARCHAR(255)?

将 NULL 插入 MySQL 时间戳