在读取和写入之间检测文档的并发数据修改



我对从数据库获取文档的方案感兴趣,某些计算是根据某些外部条件运行的,文档的一个字段已更新,然后是文档被保存,所有这些都在可能并发线程访问DB的系统中。

使其更容易理解,这是一个非常简单的例子。假设我有以下文档:

{
   ...
   items_average: 1234,
   last_10_items: [10,2187,2133, ...]
   ...
}

假设一个新项目(x)进来,需要完成五件事:

  1. 从DB中阅读文档
  2. 删除last_10_items中的第一个(最古老的)项目
  3. 将X添加到数组的末端
  4. 重新计算平均*并将其保存在items_average中。
  5. 将文档写入DB

*注意:选择平均计算是一个非常简单的示例,但是问题应根据文档中现有的数据和新数据考虑更复杂的操作(即,与$inc运算符可求解的某些东西无法解决)

这肯定在单线程系统中很容易实现,但是在并发系统中,如果2个线程想遵循上述步骤,则可能发生不一致,因为两者都会在不考虑和/的情况下更新last_10_itemsitems_average值。或覆盖并发更改。

那么,我的问题是如何处理这种情况?有没有办法检查或反应基础文档在步骤1和5之间更改的事实?是否有像Redis的手表或关系DBS中的"同时修改错误"?

谢谢

在数据库系统中,它使用内存检查和回滚方案,类似于交易记忆。

简而言之,它只是监视您指定的共享内存部分,然后进行比较,交换或加载以及链接或测试和设置之类的事情。因此,如果在交易过程中更改了任何内存内容,它将中止并重试,直到该共享内存没有冲突操作。

例如,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

最新更新