PouchDB and CouchDB were designed for one main purpose: sync. Jason Smith has a great quote about this:

The way I like to think about CouchDB is this: CouchDB is bad at everything, except syncing. And it turns out that's the most important feature you could ever ask for, for many types of software."

When you first start using CouchDB, you may become frustrated because it doesn't work quite like other databases. Unlike most databases, CouchDB requires you to manage revisions (_rev), which can be tedious.

However, CouchDB was designed with sync in mind, and this is exactly what it excels at. Many of the rough edges of the API serve this larger purpose. For instance, managing your document revisions pays off in the future, when you eventually need to start dealing with conflicts.

 

CouchDB sync

CouchDB sync has a unique design. Rather than relying on a master/slave architecture, CouchDB supports a multi-master architecture. You can think of this as a system where any node can be written to or read from, and where you don't have to care which one is the "master" and which one is the "slave." In CouchDB's egalitarian world, every citizen is as worthy as another.

(Thanks to IBM for the image: http://www.ibm.com/developerworks/library/wa-couchdb/)

When you use PouchDB, CouchDB, and other members of the Couch family, you don't have to worry which database is the "single source of truth." They all are. According to the CAP theorem, CouchDB is an AP database, meaning that it's Partitioned, every node is Available, and it's only eventually Consistent.

To illustrate, imagine a multi-node architecture with CouchDB servers spread across several continents. As long as you're willing to wait, the data will eventually flow from Australia to Europe to North America to wherever. Users around the world running PouchDB in their browsers or Couchbase Lite/Cloudant Sync in their smartphones experience the same privileges. The data won't show up instantaneously, but depending on the Internet connection speed, it's usually close enough to real-time.

In cases of conflict, CouchDB will choose an arbitrary winner that every node can agree upon deterministically. However, conflicts are still stored in the revision tree (similar to a Git history tree), which means that app developers can either surface the conflicts to the user, or just ignore them.

In this way, CouchDB replication "just works."

 

Setting up sync

As you already know, you can create either local PouchDBs:

var localDB = new PouchDB('mylocaldb')

or remote PouchDBs:

var remoteDB = new PouchDB('http://localhost:5984/myremotedb')

This pattern comes in handy when you want to share data between the two.

The simplest case is unidirectional replication, meaning you just want one database to mirror its changes to a second one. Writes to the second database, however, will not propagate back to the master database.

To perform unidirectional replication, you simply do:

localDB.replicate.to(remoteDB).on('complete', function () {
// yay, we're done!
}).on('error', function (err) {
// boo, something went wrong!
});

Congratulations, all changes from the localDB have been replicated to the remoteDB.

However, what if you want bidirectional replication? (Kinky!) You could do:

localDB.replicate.to(remoteDB);
localDB.replicate.from(remoteDB);

However, to make things easier for your poor tired fingers, PouchDB has a shortcut API:

localDB.sync(remoteDB);

These two code blocks above are equivalent. And the sync API supports all the same events as thereplicate API:

localDB.sync(remoteDB).on('complete', function () {
// yay, we're in sync!
}).on('error', function (err) {
// boo, we hit an error!
});
 

Live replication

Live replication (or "continuous" replication) is a separate mode where changes are propagated between the two databases as the changes occur. In other words, normal replication happens once, whereas live replication happens in real time.

To enable live replication, you simply specify {live: true}:

localDB.sync(remoteDB, {
live: true
}).on('change', function (change) {
// yo, something changed!
}).on('error', function (err) {
// yo, we got an error! (maybe the user went offline?)
});

However, there is one gotcha with live replication: what if the user goes offline? In those cases, an error will be thrown and replication will stop.

You can allow PouchDB to automatically handle this error, and retry until the connection is re-established, by using the retry option:

localDB.sync(remoteDB, {
live: true,
retry: true
}).on('change', function (change) {
// yo, something changed!
}).on('paused', function (info) {
// replication was paused, usually because of a lost connection
}).on('active', function (info) {
// replication was resumed
}).on('error', function (err) {
// totally unhandled error (shouldn't happen)
});

This is ideal for scenarios where the user may be flitting in and out of connectivity, such as on mobile devices.

 

Canceling replication

Sometimes, you may want to manually cancel replication – for instance, because the user logged out. You can do so by calling cancel() and then waiting for the 'complete' event:

var syncHandler = localDB.sync(remoteDB, {
live: true,
retry: true
}); syncHandler.on('complete', function (info) {
// replication was canceled!
}); syncHandler.cancel(); // <-- this cancels it

The replicate API also supports canceling:

var replicationHandler = localDB.replicate.to(remoteDB, {
live: true,
retry: true
}); replicationHandler.on('complete', function (info) {
// replication was canceled!
}); replicationHandler.cancel(); // <-- this cancels it
 

Deleting replicated databases


One thing to note about replication is that it tracks the data within a database, not the database itself. If you destroy() a database that is being replicated to, the next time the replication starts it will transfer all of the data again, recreating the database to the state it was before it was destroyed. If you want the data within the database to be deleted you will need to delete via remove() or bulkDocs(). Thepouchdb-erase plugin can help you remove the entire contents of a database.

 

Fancy replication


Any PouchDB object can replicate to any other PouchDB object. So for instance, you can replicate two remote databases, or two local databases. You can also replicate from multiple databases into a single one, or from a single database into many others.

This can be very powerful, because it enables lots of fancy scenarios. For example:

  1. You have an in-memory PouchDB that replicates with a local PouchDB, acting as a cache.
  2. You have many remote CouchDB databases that the user may access, and they are all replicated to the same local PouchDB.
  3. You have many local PouchDB databases, which are mirrored to a single remote CouchDB as a backup store.

The only limits are your imagination and your disk space.

When you replicate between two remote databases, the changes flow through PouchDB. If this is not what you want, then you should POST directly to the CouchDB _replicate endpoint, as described in the CouchDB replication guide.
 

pouchdb sync的更多相关文章

  1. 使用PouchDB来实现React离线应用

    最近听到有同学在讨论关于数据上传遇到离线的问题,因此在这里介绍一下PouchDB. PouchDB 是一个开源的javascript数据库,他的设计借鉴于Apache CouchDB,我们可以使用他来 ...

  2. pouchdb Conflicts

    Conflicts are an unavoidable reality when dealing with distributed systems. And make no mistake: cli ...

  3. PouchDB 基础

    GUIDES http://pouchdb.com/guides/ 1.建立couchDB环境 下载并安装CouchDB: https://couchdb.apache.org/#download 测 ...

  4. pouchdb快速入门教程

    a:focus { outline: thin dotted #333; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2p ...

  5. Gradle project sync failed

    在Android Studio中运行APP时出现了以下错误: gradle project sync failed. please fix your project and try again 解决的 ...

  6. svn sync主从同步学习

    svn备份的方式有三种: 1svnadmin dump 2)svnadmin hotcopy 3)svnsync.  优缺点分析============== 第一种svnadmin dump是官方推荐 ...

  7. ASP.NET sync over async(异步中同步,什么鬼?)

    async/await 是我们在 ASP.NET 应用程序中,写异步代码最常用的两个关键字,使用它俩,我们不需要考虑太多背后的东西,比如异步的原理等等,如果你的 ASP.NET 应用程序是异步到底的, ...

  8. publishing failed with multiple errors resource is out of sync with the file system--转

    原文地址:http://blog.csdn.net/feng1603/article/details/7398266 今天用eclipse部署项目遇到"publishing failed w ...

  9. 解决:eclipse删除工程会弹出一个对话框提示“[project_name]”contains resources that are not in sync with"[workspace_name...\xx\..xx\..\xx]"

    提示“[project_name]”contains resources that are not in sync with"[workspace_name...\xx\..xx\..\xx ...

随机推荐

  1. UVA 1639(组合数学)

    根据组合数公式C(m,n),由于m可能达到20万,因此转换为ln,之后可以表达为ln(m!)-ln(n!)-ln((m-n)!); 求每一个c[n]时,也要根据杨辉三角求组合数进行转化. 注意long ...

  2. ERP部门的添加(十一)

    功能需求: 1.有部门管理权限的人员进行添加部门基本信息. 2.有部门权限管理的人员查询部门基本信息. 3.有部门权限管理的人员进行修改部门基本信息. 4.在一个页面中实现,使用弹出对话框方式 存储过 ...

  3. ERP仓库管理系统查询(十)

    需求:    1.根据仓库编号,获取仓库信息绑定至页面相关控件. 2.根据仓库编号,获取管理员信息绑定到页面相关控件 修改的界面: <%@ Page Language="C#" ...

  4. Java 集合深入理解(13):Stack 栈

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 今天心情不错,再来一篇 Stack ! 数据结构中的 栈 数据结构中,栈是一种线性数据结构,遵从 LIFO(后进先出)的操 ...

  5. 瓷砖铺放 (状压DP+矩阵快速幂)

    由于方块最多涉及3行,于是考虑将每两行状压起来,dfs搜索每种状态之间的转移. 这样一共有2^12种状态,显然进行矩阵快速幂优化时会超时,便考虑减少状态. 进行两遍bfs,分别为初始状态可以到达的状态 ...

  6. Inherits、CodeFile、CodeBehind的区别

    Inherits.CodeFile.CodeBehind 在 ASP.NET 中使用代码隐藏方法来设计Web 窗体,可使页代码能够更清晰地从 HTML 内容中分离到完全单独的文件中. 通常一个 @pa ...

  7. C++ STL算法系列 unique

    类属性算法unique的作用是从输入序列中“删除”所有相邻的重复元素. 该算法删除相邻的重复元素,然后重新排列输入范围内的元素,并且返回一个迭代器(容器的长度没变,只是元素顺序改变了),表示无重复的值 ...

  8. sdust 2410 Mine Number

    今天看了3个这种题了  枚举第一行即可 #include<cstdio> #include<cstring> #include<iostream> #include ...

  9. 阿里云2003服务器VPN搭建[转自阿里云官方论坛]

    VPN可以应用在很多方面,很多公司只是拿它接入公司内部网络,但我们做安全的需要的是利用它做跳板上网(还有提高网速).这篇文章主要是针对这种应用来说的,包括公网VPN的配置. 服务器配置 前奏:关闭防火 ...

  10. win7 一些快捷系统工具命令

    1.cleanmgr: 打开磁盘清理工具 2.compmgmt.msc: 计算机管理 3.conf: 启动系统配置实用程序 4.charmap: 启动字符映射表 5.calc: 启动计算器 6.chk ...