Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.06.2014, 17:58   #1
Winexcel
Форумчанин
 
Регистрация: 26.08.2013
Сообщений: 187
По умолчанию Критическая секция в РБД

Всем доброго времени суток!
Не давно начал изучать sql, читаю Мартина Грабера за 2014, и задался таким вопросом, а как же синхронизировать рбд, в книге нашёл информацию только о блокировках, но конкретных примеров этого нет, кто может, подскажите как оптимизировать запрос UPDATE с синхронизацией(говорю так потому что не знаю как правильно это называется в sql, возможно угадал )
Winexcel вне форума Ответить с цитированием
Старый 04.06.2014, 21:29   #2
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,755
По умолчанию

Цитата:
Сообщение от Winexcel Посмотреть сообщение
подскажите как оптимизировать запрос UPDATE с синхронизацией(говорю так потому что не знаю как правильно это называется в sql, возможно угадал )
Это что-то новенькое.

В СУБД на клиентском уровне нет потоков в том смысле как в ОС, а конкурентный доступ выполняется через транзакции, составной частью реализации которых являются блокировки. Ядро СУБД где-то внутри себя создает и завершает потоки ОС по мере надобности, но наружу видны только транзакции.

Взаимодействие транзакций из разных сеансов описывается уровнями изоляции транзакций, их обозначают аббревиатурой ACID. Почитай в Википедии. Не помню, описывается это у Грабера или нет.

Реализация транзакций зависит от конкретной СУБД. В стандарте SQL предусмотрены команды select for update, commit и rollback, они должны быть реализованы в любой СУБД. Каждая СУБД может иметь дополнительные команды для управления транзакциями, но стандарта на них нет.

Я угадал с ответом?
Vapaamies вне форума Ответить с цитированием
Старый 04.06.2014, 22:07   #3
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Цитата:
Я угадал с ответом?
Как по мне угадал на 100%. По крайней мере на базе SQL сопроцессов нет а значит и синхронизация не актуальна, хотя некоторые СУБД умудряются зарулить на других языках типа Java (Оракл) такие вещи.
И было бы неплохо узнать откуда ноги растут у сего вопроса.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 05.06.2014, 08:25   #4
Winexcel
Форумчанин
 
Регистрация: 26.08.2013
Сообщений: 187
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Как по мне угадал на 100%. По крайней мере на базе SQL сопроцессов нет а значит и синхронизация не актуальна, хотя некоторые СУБД умудряются зарулить на других языках типа Java (Оракл) такие вещи.
И было бы неплохо узнать откуда ноги растут у сего вопроса.
А ноги растут вот откуда : я собираюсь писать клиент-серверное приложение, где допустим в онлайне на данный момент находится 100 человек, на сервере есть скрипт в котором есть поиск игры, и этот скрипт выводит в поиске например игру с 10тью слотами для игры, когда человек входит в данный слот в БД некое поле COUNT = COUNT + 1( это на sql запросе) вот это и есть запись UPDATE, но случается такое иногда что если одновременно около 30 человек будут стучатся в данную игру со слотами, происходит переполнение, ну например 12 человек зашло в игру где всего 10 слотов. Вот и интересно как бы это решить.
Winexcel вне форума Ответить с цитированием
Старый 05.06.2014, 21:06   #5
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,755
По умолчанию

В СУБД подобные задачи решаются добавлением записей в таблицу сеансов и контроля либо одновременного количества записей в таблице, либо количества активных записей (что-то вроде очереди).
Vapaamies вне форума Ответить с цитированием
Старый 07.06.2014, 16:10   #6
Winexcel
Форумчанин
 
Регистрация: 26.08.2013
Сообщений: 187
По умолчанию

Цитата:
Сообщение от Vapaamies Посмотреть сообщение
В СУБД подобные задачи решаются добавлением записей в таблицу сеансов и контроля либо одновременного количества записей в таблице, либо количества активных записей (что-то вроде очереди).
Я читал http://habrahabr.ru/post/137979/ , вот это поможет? Я прост новичок в sql, на данный момент только связанные подзапросы изучаю
Winexcel вне форума Ответить с цитированием
Старый 07.06.2014, 16:15   #7
Winexcel
Форумчанин
 
Регистрация: 26.08.2013
Сообщений: 187
По умолчанию

Вот к примеру есть запрос:
Код:
UPDATE wow_game
SET Num_People = Num_People +1
WHERE id = 1
id тут есть игра, Num_People = кол-во людей в слотах, есть отдельное поле COUNT в котором указывается сколько всего есть слотов, на пхп я использую SELECT и сравниваю оба эти поля, если поле Num_People < COUNT то мы делаем UPDATE, дак вот если просто заблокировать то поле полностью, даже сделать недоступным для READ_ONLY, то тогда думаю выйдет что-то путёвое, или заставить PHP ждать ответа от БД.
Winexcel вне форума Ответить с цитированием
Старый 07.06.2014, 16:30   #8
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,755
По умолчанию

Цитата:
Сообщение от Winexcel Посмотреть сообщение
Я читал http://habrahabr.ru/post/137979/ , вот это поможет?
Решение зависит от конкретной СУБД, они бывают двух видов -- блокировочные и версионные. Блокировочные склонны порождать костыльные решения, а версионные православны, но ими нужно научиться пользоваться.

Цитата:
Сообщение от Winexcel Посмотреть сообщение
когда человек входит в данный слот в БД некое поле COUNT = COUNT + 1( это на sql запросе) вот это и есть запись UPDATE
Должно быть примерно так:
Код:
insert into game_sessions
  (game_id, session_id)
select
  :game_id, :session_id -- передаются как параметры
where
  (select count(*) from game_sessions where game_id = :game_id) <= 10;
Тут проверка и добавление делаются за один шаг, что транзакционно безопасно и должно держать большую нагрузку. Была ли вставлена запись, можно узнать средствами API сервера, что-то вроде SQL%rowcount или "affected rows".

Подразумевается, что пользователь помнит session_id в пользовательском окружении (на сервере или на клиенте), а при выходе из игры запись удаляется. Можно хранить историю всех сеансов, для чего ввести поле active и проверять его в подзапросе.
Vapaamies вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Потоки, Критическая секция, виснет форма. Sonny01 Помощь студентам 3 14.10.2012 18:26
секция resource goluzov Win Api 0 04.08.2012 09:16
Критическая секция между потоками на разных ядрах 3D Hunter Win Api 11 26.02.2012 08:06
КРИТИЧЕСКАЯ ОШИБКА benjaminfran Общие вопросы Delphi 11 15.02.2008 11:23