【vte.cx应用】15. 事务处理和编号处理

今天我将简要解释交易处理和编号的执行方法。由于内容将显得有些教条主义,请做好心理准备以便阅读。

補償交易的噩梦

如果问到事务处理的目的是什么,那就是为了管理正确的信息。通过事务提交来表示“正确的信息”,通过事务回滚来表示“不正确的或尚未接受的信息”,从而始终保持一致的状态。

许多KVS(如MongoDB和Cassandra)不支持ACID事务。由于易于使用,我们经常看到使用它们构建业务应用程序的案例,但大多数情况下似乎都被事务处理所困扰。

而且,我也看到了一些人试图自力解决问题,结果变得更糟。这就是所谓的补偿交易。

然而,不能轻视交易处理。我自己也有几年前的糟糕经历。

首先,请您阅读关于赔偿交易的恶梦。

你有读吗?

不使用ACID事务而尝试通过补偿事务等解决问题的是那些对自己能力有自信的工程师常常陷入的陷阱。
因为他们理解事务,所以对运营持有不慎乐观态度。
正如博客中所写,这浪费时间并给周围人带来不幸。

如同我师傅中岛先生所言,

在云计算的名义下,可能会废弃已经建立的现有系统的构建经验,导致现场系统的再次混乱,这令人担忧。努力可能会被浪费在不太创造附加价值的新规范和替代上,浪费了优秀而宝贵的智力和时间,这是一个忧虑。

这就是情况了吧。

在開發業務應用程序時,請認識到ACID事務處理是必需的。
我們應該選擇支援ACID事務處理的中間件來使用。

引入事务脚本模式。

在只支持ACID事务的情况下,我认为仍然不足够。

传统的代码嵌入式事务管理,如在主机故障中心、数据库管理系统和JDBC等中使用的提交/回滚功能,一直被认为存在问题。

原因是因为很难发现由于遗漏了commit或rollback等代码而导致的错误。

从源代码中提取出所有内容,然后搜索”抜け”。所谓”抜け”是指只有开始点的处理,例如只执行了SELECT FOR UPDATE,但没有提交或回滚的部分。翻阅他人的源代码以追踪逻辑是非常痛苦的工作。打击精神。

因此,我们考虑使用一种名为事务脚本的设计模式,在API的入口和出口处设置事务点来进行处理。简而言之,如果API内部的操作全部成功,则进行提交(commit),如果失败,则进行回滚(rollback)。

这是服务的最小单位变成原子,是一个易于理解的模式。

在vte.cx上的交易处理

vte.cx支持基于Feed的原子事务(隔离级别:REPEATABLE READ),同时支持基于Entry的版本比较(隔离级别:SNAPSHOT ISOLATION)。

transaction.png

按照Feed单元进行原子事务处理。

Alternatively:
针对Feed单元进行原子交易处理。

通过事务脚本模式,Feed中包含的Entry将在一个事务中执行。

例如,通过在Feed中放入库存和订单两个条目,可以将库存分配和订单注册作为一个事务执行。

请参考交易处理的详细信息。

Entry单位的版本比较

当Feed中的Entry包含有版本号。
在进行整体PUT更新Feed时,会通过与原版本号进行比较来检查是否可以进行更新。如果原版本号不同,则表示已经被他人更新,这将导致乐观锁错误。

这可以与上述的以Feed为单位的原子交易结合使用。换句话说,如果任何一个条目发生乐观锁冲突错误,将导致整个Feed的更新被回滚。

关于采番处理

在vte.cx上,我们提供了用于编号的API。
编号也是一种没有ACID事务实现就很难实施的功能。
我们采用了写入锁定,在比使用Feed的PUT更新更快地获取数据。

使用“PUT /{任意的URI}?_allocids={採番數}”的方式,對於每個指定的URI,按照所指定的採番數進行編號。

还有其他一些API,例如setids、addids和rangeids。

请参考编号和编号计数器以获取详细信息。

采番处理和Feed更新的结合

我经常希望以采番值作为键进行注册。

如果这种情况发生,就将已经分配的值设置到Entry中,并进行Feed的更新。
如果Feed更新出现错误并进行回滚,已经分配的键将不会恢复。
如果可以丢弃该值,那么可以保持不变,如果想要填补空缺,可以使用addids()进行负数的分配。

顺便说一句,在进行POST注册时,如果没有指定键(Key),系统会自动分配一个独特的编号给它。(自动分配编号)

请查阅Entry注册以获得详细信息。

今天就到这里了。
明天会介绍有关安全性的内容。
好了,谢谢大家。