本文试图对数据库异步操作进行一个入门式的介绍,并且对在应用中常遇到的简单的问题给出方案建议.
文档结构:
- 数据库的同步和异步
- websql
- 异步下的一些状况和方案
1.数据库的异步和同步
通常我们使用DB的方式都是同步的:连接上DB后,我们发起一个sql操作请求,等待操作结束和结果返回后,继续下一步操作。这个等待的过程会导致:
1.之后的操作在结果返回前不会被执行;
2.等待导致被动阻塞,被动阻塞甚至不会释放相关资源,从而进一步造成资源闲置。因此,同步方式的缺点在于并发能力随着sql操作请求耗时的增加而急剧降低,尤其当某一步sql操作耗时较大时
我们也可以选择使用异步的方式来操作DB:连接上DB后,我们发起一个sql操作请求,同时定义一个该sql操作完成后被触发执行的方法,然后程序不进行任何等待,直接做下一步的操作。真正的sql操作在另一个时刻被单独执行,完成后调用我们定义好的方法。由于DB操作通常是最耗费时间的,因此在异步操作中,常常是程序的主流程很快的被执行完成,而大部分的DB操作甚至还没有开始,他们会在随后开始运行,但此时已不再有被堵塞的线程了——就像一个蓄水池,把过量的河水拦住,避免洪水泛滥。
异步操作常常依赖于回调的方式,从而把原本顺序的连贯的逻辑拆开来放在不同的地方,复杂情况下就有点四分五裂的感觉了.考虑到容错和异常处理的话,在代码组织和维护上就需要大大的费神了。对于异步操作的简化需要语言级别的支持,而对于常见的js和java而言,缺乏更加强大的机制,因此回调是唯一选择
当然,对于DB本身而言,都是同步的。不存在一个叫‘异步数据库’的产品。
2.WebSQL
在.net平台上,提供了这种异步操作DB的方式,并且支持的相当优雅。而Java用户可以参考ADBCJ。本文则要谈的是另一个平台:浏览器上的类似产品,相对前者而言有些简陋的WebSQL。
WebSQL包括一个sqlite3数据库和一个同时支持同步和异步方式的API,支持这个WebSQL的浏览器有chrome,safari和opera。原本WebSQL是被当做HTML5的一部分被推广的,但是最近'有关部门'停止了维护,在将来会由‘indexedDB’所取代,同样的,‘indexedDB’也支持异步的方式。
WebSQL主要用于在客户端存储一些较为复杂的关系型数据,这些数据需要能够按照多种条件组合被查询出来;如果仅仅是通过key/id来查询数据的,可以适用简单的支持更广泛的localStorage。
对于支持WebSQL的浏览器,可以通过db = openDatabase(‘WebDB’, '1.0', 'db on client side', 1 * 1024 * 1024) 获取数据库的连接,如果指定的数据库不存在,在浏览器端创建一个名为WebDB,版本为1.0, 大小1M的数据库。
----WebSQL的基本使用
上文中,获取到的db是一个js对象,里面封装了异步使用数据库的方法。
假设DB中有表blogs{id, title, gmtCreate}, 页面依赖了jQuery
var lastId = 10;
db.transaction() {
function(t) {
t.executeSql('select * from blogs where id > ? limit 5 order by id asc', [lastId], function(t, result){
$('.blogs').append('' + result.title + '');
})
}
}
这一段代码做的事情是:把id>lastId的5条记录按照先后顺序展示在blogs列表中。
这段代码背后的执行过程是这样的:
1. executeSql执行的时候,仅仅是把要执行的sql语句和对应的回调方法推送到一个全局队列S中,然后马上返回
2. 接下来的某个时候,全局队列S中的sql语句按序被调用
3. 当sql成功返回时,对应的回调方法(连同sql执行结果)会被推送到另一个全局队列C中,执行sql的程序马上返回
4. 接下来的某个时候,全局队列C中的回调方法按序被调用,从而完成整个执行过程
在这里可以找到关于WebSQL的详细规范和API文档
3.异步下的一些状况
3.1 数据过时问题
在js中,定义的回调函数是可以使用定义外的一些数据的,假设全局有个counter的变量,负责sql执行次数的统计,我们需要在sql执行完后把’自己是第几个执行的sql‘打印出来。在同步方式下,我们会把这个counter++放在sql执行的语句之后,然后输出counter;但是在异步方式下,我们必须把这个步骤放进回调函数中,而不是t.executeSQL()之后,因为sql真正的执行常常是在这个函数调用完成之后做的,这意味着,当回调函数开始执行的时候,counter的值已经被累加过了,如果executeSQL()多调用了几次,那么counter的数值就会被多次累加并且所有的回调函数中输出的counter都是一个值
这也要求我们,对于引用外部的值需要保持刻意的谨慎,一方面,它随时可能被改动;另一方面,对它的改动很可能不是按照你预期的方式进行的
最理想的方式所有需要用的数据都在’推送回调函数至全局队列C‘这个步骤时都一起传给回调函数,保证数据之间的隔离。但是对于WebSQL,我们看到它的API并不支持这么自由的应用方式,并且它现在已经停止维护了。
所以退而求其次的,我们尽量将会造成影响的改动推迟到回调函数中去完成。
3.2 最后的输出问题
在饭店,无论多么的和服务员异步,她最后总得说一句:“菜已经齐了,先生”,这句话就是’最后的输出‘。操作数据库的时候,很少是一个表就能完成的,碰到需要同时去多个表拿数据组装的场合,我们就得知道那个所有数据都查询到并组装好的’菜齐了的‘时刻。
同步场合下,这根本不是个问题,大不了就一直死等下去,但只要返回了,数据就一定有了。
异步场合下,这几个sql各干各的,回调函数彼此平行,互不了解,就不知道是不是全部数据都有了。为了解决这个问题,通常需要引入一个对所有相关回调函数都知道并可以操作的变量,从而对全局有整体的了解。
这个变量可以是,比如状态表,当状态表中的所有状态都是’OVER‘的时候,我们就知道全部’OVER‘了;又比如计数器,要求计数到指定阀值。根据“数据过时问题”中的描述,对这个变量的更改操作需要放进回调函数中去。
参考Java中的Barrier,其原理是,要求指定数量的线程完成某个操作后,程序才继续往下走, 我们可以设置一个Barrier形式的变量b,在executeSQL()调用前b.counter+1,在对应的回调函数执行后,b.counter-1,当b.counter再度回到0的时候,表示’全部执行完毕‘;如果预先知道sql执行的次数,则设置b.counter,并且省略'调用前b.counter+1'的步骤。这种方式主要解决,状态表复杂或者计数阀值预先不可知的情况
在异步场合下,感知’菜齐了‘的方式当然也是异步的,在变量中封装几个方法吧。
3.3 应用设计
无论是同步还是异步,都只有针对应用场景作最优设计才能最大限度的发掘系统潜力,神奇的应用设计一样具有把异步处理’化神奇为腐朽‘的能力。
比如,我们知道DB操作时非常消耗时间的,如果你把一次调用做成调用三次,那么你就过度给力了。在WebSQL中,由于executeSQL()没有提供对where id in(某个数组)操作的原生支持,需要我们自己去做些额外的操作,像自己拼装sql或者根据该数组大小来拼装带对应数目的’?‘的sql。如果不注意直接在数组循环里逐个调用sql,耗时就会成倍增加。
又比如,上文所讲,不可能全部异步,总会有一些环节是要严格按照先后顺序的,比如这么一个场景:user(id, name) box(id, uid), thing(id, bid, what),必须要知道user,才可以查到box,继而才能查到thing,响应时间是比较长的,因为查到user后,查询box的sql会推入到全局队列等待调度,而在同步场合下是没有这个等待时间的,它会被立刻执行。这意味着这种环节数越多,一个请求的响应时间就越长,因此必须减少环节数,增加单个环节并行执行的sql数。对于例子中的解决办法,如果这种获取是常用的,则可能的方式是在thing中冗余一个uid,从而在user获取到后,并发执行两个查询:box和thing。
分享到:
相关推荐
但是,此插件支持sql的异步执行,其中MSOpenTech的WebSQL插件是完全同步的。 支持平台 该插件仅支持windows平台,因为大多数其他平台( ios , android等)已本机支持WebSQL。 您还可以将此插件与结合。 它们共同...
(websql) Android 浏览器 2.1+ (websql), 4+ (indexeddb) Android 网页客户端、iOS 网页客户端 (websql) Opera 10+ (websql), Opera 15+ (indexeddb) 特征 IndexedDB、WebDatabase 和 WebStorage 存储机制上的统一...
这意味着它是一个具有多个后端(IndexedDB、WebSQL、localStorage)的异步浏览器存储,旨在提供更好的离线体验。 与localForage的主要区别: 批量获取/设置支持 回调或承诺 浏览器友好 受启发的简单 API 发展...
localForage通过将异步存储(IndexedDB或WebSQL)与简单的localStorage的API一起使用来改善Web应用程序的脱机体验。 localForage在不支持IndexedDB或WebSQL的浏览器中使用localStorage。 有关请参见 。 要使用...
这个插件基本上是一个IndexedDB-to-WebSql适配器 安装 通过安装。 对于Cordova CLI 4.x ,请使用GIT URL语法: cordova plugin add https://github.com/ABB-Austin/cordova-plugin-indexeddb-async.git 对于...
localForage 有一个优雅降级策略,若浏览器不支持 IndexedDB 或 WebSQL,则使用 localStorage。在所有主流浏览器中都可用:Chrome,Firefox,IE 和 Safari(包括 Safari Mobile)。 localForage 提供回调 API 同时...
dbOption:可以通过设置为“ WebSQL”或“ IndexedDB”来选择存储。 “无”或null将不使用任何数据库。 onError(可选):如果出现任何错误(错误类型,错误数据),则将调用此方法,有关更多详细信息,请参见...
localForage通过将异步存储(IndexedDB或WebSQL)与简单的localStorage的API一起使用来改善Web应用程序的脱机体验。 localForage在不支持IndexedDB或WebSQL的浏览器中使用localStorage。 请参阅[有关详细的兼容性...
使用简单但功能强大的API包装IndexedDB,WebSQL或localStorage。 localForage是一个JavaScript库,通过使用带有简单的类似于localStorage的API的异步数据存储来改善Web应用程序的脱机体验。 它允许开发人员存储多种...
“ localForage是一个JavaScript库,可通过简单的类似于localStorage的API使用异步存储(通过IndexedDB或WebSQL,如果有的话)来改善Web应用程序的脱机体验。” 所有主流浏览器(包括移动设备)都支持它。 用法 ...
将 ASP.NET 2.0 应用程序服务配置为使用 SQL Server 2000 或 SQL Server 2005 ASP.NET 2.0 中的数据源控件 使用 ASP.NET 2.0 ObjectDataSource 控件 ASP.NET 2.0 的内部变化 使用SQL Cache Dependency 代替 ...
普遍采用了异步读取的方式来减少系统开销。一些改进的方法也避免不了这一问题。 ' DBTREE 1.3.2 FOR ASP & ACCESS ' lastupdate:2006-09-10 ' author 雷晓宝 ' 许可协议:GUN LGPL ' e-mail: lxbzmy@163.com ' qq:...
服务器端渲染的React应用程序,该应用程序已预先填充了服务器上的数据,并使用localstorage / WebSQL / IndexedDB在客户端进行了重新水化处理。 使用Websocket将价格更新推送到前端,并使用IP映射将客户端分配给...
网上的两个不错的资源示例,现整合到一齐,有需要的朋友可以学习一下,入门研究不错的说~ 数据库采用sqlserver2000,在dbsql文件夹下,在企业管理器中附加数据库即可。 数据库连接字符串请在web.config中修改。
将您的数据存储在浏览器可以提供的最佳可用存储解决方案中(IndexedDB / WebSQL或localstorage作为备用) 从IE8开始支持所有浏览器。 有关完整列表,请检查: , 和 一切都是异步的,并使用承诺 使用服务或指令 ...
DJJob允许PHP Web应用程序异步处理长时间运行的任务。 它是一个PHP端口 (在Shopify开发),已在生产的SeatGeek自2010年4月被使用。 像delay_job一样,DJJob使用jobs表来持久化和跟踪挂起,进行中和失败的作业。 ...
此组件编写环境为.NET 4.0,可用来操作常用的数据库,内置Oracle、Sqlserver、Mysql、SQLite、Odbc、Oledb等数据库访问方式,支持Winform、wpf、webform、Silverlight(提供Silverlight专用类库,编码上与其它平台无...
7.7.7 sql xml oledb提供程序中的for xml 7.7.8 批量加载 7.7.9 未来的支持 7.8 使用sqlxml和.net 7.9 小结 第8章 提供程序:ado.net和数据提供程序 8.1 如何选择 8.2 保留ole db:ole db概念...
为 Web 访问配置策略和过滤器 72 过滤 Access Gateway 连接的必要条件 73 基于 Access Gateway 连接应用策略过滤器 73 基于现有 Access Gateway 策略应用策略过滤器 73 将策略应用于除基于 Access Gateway 的连接...