我使用node.js每10秒查询一次MySQL数据库表。使用socket.io,在每10秒进行一次数据库查询后,每个连接的浏览器将从该查询中收到一组唯一的行。
问题:按照我实现此方式的方式,每隔10秒钟,有多个浏览器可能会收到相同的行集。我使用了一些检出系统(如下所示)来标记已经发送到另一个浏览器的行,但它似乎并不是一直有效。如何保证每个浏览器每次都获得一组唯一的行?
换句话说,其他浏览器同时查询数据库比锁定行更快!
实施
每10秒发生以下情况
SELECT * FROM table WHERE checkout = 0
io.sockets.send
向所有连接的浏览器发送消息,说明行可用socket.emit('ready')
ready
emit,再次查询数据库以选择3行,然后更新表以将这3行的checkout
列设置为1
显然,第二个浏览器导致SELECT...
查询的时间比第一个浏览器用checkout = 1
更新行的时间要短。还有另一种方法可以排队吗?
截图
正如您在2个浏览器同时打开的屏幕截图中所看到的,通常两个浏览器都会获得相同的行集。如图所示,行的ID为console.log
。
CODE
Node.js的
io.sockets.on('connection', function(socket) {
// Client ready to take jobs after receiving broadcast
socket.on('ready', function() {
getListings(function(listings) {
socket.emit('job', listings); // send jobs
});
});
});
var getListings = function(callback) {
client.query('SELECT * FROM table ' +
'WHERE job_checkout = 0 ' +
'ORDER BY listing_id ASC ' +
'LIMIT 0, 3',
function(error ,results, fields) {
if (error)
throw error;
// Checkout listing now!
checkoutListings(results);
callback(results);
});
};
var checkoutListings = function(listings) {
for (var i = 0; i < listings.length; i++) {
checkoutListing(listings[i]);
}
}
var checkoutListing = function(listing) {
client.query('UPDATE table ' +
'SET job_checkout = 1 ' +
'WHERE listing_id = ?',
[ listing.listing_id ]);
}
答案 0 :(得分:0)
简单的解决方案(如果性能不是一个大问题)是一个锁定你触摸的每一行以便阅读的事务 - 如果其他人试图在你的选择和插入之间读取,那么他们将不得不等到你的锁被释放< / p>
答案 1 :(得分:0)
在选择行之前更新行。例如
update table
set job_checkout = uniqueNumber
where job_checkout = 0
limit 10
uniqueNumber可以是进程/线程ID,浏览器客户端ID,或者在node.js环境中适合的东西(我不熟悉它)。现在选择具有该唯一job_checkout的行。