Я использую node.js для запроса таблицы базы данных MySQL каждые 10 секунд. Используя socket.io, после запроса к базе данных каждые 10 секунд каждый подключенный браузер получит уникальный пакет строк из этого запроса.
Проблема: Благодаря тому, как я это реализовал, каждые 10 секунд существует вероятность того, что более 1 браузера получат один и тот же набор строк. Я использовал некоторую систему проверки (как показано ниже), чтобы отметить строки, которые уже были отправлены в другой браузер, но, похоже, не работает все время. Как я могу гарантировать, что каждый браузер каждый раз получает уникальный набор строк?
Другими словами, одновременный запрос базы данных другими браузерами быстрее, чем блокировка строк!
Осуществление
Каждые 10 секунд происходит следующее
- Приложение Node.js запрашивает таблицу базы данных MySQL
SELECT * FROM table WHERE checkout = 0
- Если результат возвращается, сервер node.js
io.sockets.send
- сообщение для всех подключенных браузеров о том, что строки доступны
- Все подключенные клиенты отвечают
socket.emit('ready')
- Сервер получает emit
ready
, снова запрашивает базу данных, чтобы выбрать 3 строки, затем обновляет таблицы, чтобы задать для столбца checkout
этих 3 строк значение 1
- Затем сервер отправляет клиенту результат запроса базы данных
По-видимому, для второго браузера требуется меньше времени, чтобы вызвать запрос SELECT...
, чем для первого браузера, чтобы обновить строки с checkout = 1
. Есть ли другой способ сделать эту очередь?
Скриншот
Как вы можете видеть на скриншоте двух открытых одновременно браузеров, часто оба браузера получают одинаковый набор строк. Идентификаторы строк 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 ]);
}