我对从数据库中提取文档,根据某些外部条件运行某些计算,更新文档的某个字段然后保存文档的方案感兴趣,所有这些都在系统中可能有并发线程访问数据库。
为了便于理解,这是一个非常简单的例子。假设我有以下文件:
{
...
items_average: 1234,
last_10_items: [10,2187,2133, ...]
...
}
假设有一个新项目(X),需要做五件事:
last_10_items
items_average
中。 *注意:选择平均计算是一个非常简单的例子,但问题应该考虑基于文档中存在的数据和新数据的更复杂的操作(即不能用{{解决的问题) 1}}运营商)
这在单线程系统中很容易实现,但在并发系统中,如果2个线程想要遵循上述步骤,则可能会出现不一致,因为两者都会更新$inc
和{{ 1}}值,不考虑和/或覆盖并发更改。
所以,我的问题是如何处理这样的场景?有没有办法检查或反应在步骤1和5之间更改基础文档的事实?是否存在来自redis的WATCH或来自关系数据库的“并发修改错误”?
由于
答案 0 :(得分:0)
在数据库系统中,它使用类似于事务内存的内存检查和回滚方案。
简而言之,它只是监视您指定的共享内存部分,并执行比较和交换或加载和链接或测试和设置之类的操作。 因此,如果在事务期间更改了任何内存内容,它将中止并再次尝试,直到该共享内存没有冲突操作。
例如,GCC实现以下内容:
https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html
type __sync_lock_test_and_set (type *ptr, type value, ...)
type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...)
有关事务内存的更多信息, http://en.wikipedia.org/wiki/Software_transactional_memory