我创建了一个包含数组的对象,该数组用作工作队列。
这样的工作是这样的:
var work1 = new Work();
var work2 = new Work();
var queue = Workqueue.instance();
queue.add(work1) // Bluebird promise.
.then(function addWork2() {
return queue.add(work2);
})
.then(function toCommit() {
return queue.commit();
})
.then(function done(results) {
// obtain results here.
})
.catch(function(err){});
在这种情况下它可以工作,在我调用提交之前,我可以提交多个任务。
但是,如果是这样的话:
var work1 = new Work();
var work2 = new Work();
var queue = Workqueue.instance();
queue.add(work1)
.then(function toCommit1() {
return queue.commit();
})
.then(function done1(result1) {
// obtain result1 here.
})
.catch(function(err){});
queue.add(work2)
.then(function toCommit2() {
return queue.commit();
})
.then(function done2(result2) {
// obtain result2 here.
})
.catch(function(err){});
可能出问题了,因为如果在第二次提交之后调用了第一次提交(已经添加了两个工作/任务),则第一个提交处理程序将期望结果,但是它们都进入了第二个提交处理程序。
该任务涉及Web SQL数据库读取,还可能涉及网络访问。因此,这基本上是一个复杂的过程,因此上述问题可能会浮出水面。如果只有我可以addWorkAndCommit()
实现将add
和包裹commit
在一起的实现,但是仍然不能保证,因为addWorkAndCommit()
从某种意义上说它们是“原子的”,因为它们涉及异步调用。因此,即使有两个呼叫,addWorkAndCommit()
也可能失败。(由于JavaScript是单线程的,所以我不知道用“原子”来描述它,但是这个问题冒出来了)。
我能做些什么?
问题在于commit()
没有事务的概念,但是没有事务的概念,因此您不能明确地使两个独立的事务并行运行。根据我的理解,JavaScriptWorkqueue
是远程队列的代理,add()
并且commit()
直接调用并映射到某种具有类似接口但没有事务的远程过程调用。我也了解您不会关心第二个是否add()
真的发生在第一个之后commit()
,您只想编写两个简单的后续addWorkAndCommit()
语句,而无需在客户端代码中同步基础调用。
您可以做的是在本地周围编写一个包装器Workqueue
(如果是您的代码,则直接对其进行更改),这样队列的每次更新都会创建一个新事务,并且commit()
始终引用一个这样的事务。然后,包装程序将延迟新的更新,直到所有先前的事务都被提交(或回滚)为止。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句