Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / 3 телемаркетолога и Access / 25 сообщений из 51, страница 1 из 3
14.12.2016, 11:06
    #39366494
Толикman
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
Добрый день!

У нас осуществляется телемаркетинг тремя телемаркетологами.
Есть общий список задач на обзвон (предикторы они у нас зовутся).
По логике каждый берет в работу первого свободного и работает с ним.

Вот цепочка запросов:

Вызывается запрос на обновление (во вложении скрин схемы):
Код: sql
1.
2.
3.
4.
5.
UPDATE Предикторы_локал 
 INNER JOIN Предиктор_резервирование_фильтр 
 ON Предикторы_локал.Код = Предиктор_резервирование_фильтр.Код 
SET Предикторы_локал.Зарезервировал = [TempVars]![Телемаркетолог], 
 Предикторы_локал.[Дата резервации] = Date()+Time();



Который ссылается на запрос Предиктор_резервирование_фильтр :
Код: sql
1.
2.
SELECT TOP 1 Предиктор_резервирование_выборка.*
FROM Предиктор_резервирование_выборка;



Который ссылается на запрос Предиктор_резервирование_выборка :
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
SELECT Предикторы_локал.Код
FROM (Предикторы_локал 
 LEFT JOIN Предикторы_звонки_локал ON Предикторы_локал.Код = Предикторы_звонки_локал.Предиктор) 
  LEFT JOIN (Предикторы_отложенные_локал
   LEFT JOIN Сессии_активные ON Предикторы_отложенные_локал.Сотрудник = Сессии_активные.Сотрудник)  
 ON Предикторы_локал.Код = Предикторы_отложенные_локал.Предиктор
WHERE 
(
 ((Предикторы_отложенные_локал.Код_локал) Is Null) 
 AND ((Предикторы_звонки_локал.Код) Is Null) 
 AND ((Предикторы_локал.[Дата резервации])<DateAdd("n",-30,Date()+Time()) 
  Or (Предикторы_локал.[Дата резервации]) Is Null) 
 AND ((Предикторы_локал.Экспорт)=False)
) 
OR 
(
 ((Предикторы_локал.[Дата резервации])<DateAdd("n",-5,Date()+Time()) 
  Or (Предикторы_локал.[Дата резервации]) Is Null) 
 AND ((Предикторы_локал.Экспорт)=False) 
 AND ((Предикторы_отложенные_локал.[Отложенаня дата])<(Date()+Time())) 
 AND ((Предикторы_отложенные_локал.Сотрудник)=[TempVars]![Телемаркетолог]) 
 AND ((Предикторы_отложенные_локал.Звонок_рез_локал) Is Null)
) 
OR 
(
 ((Предикторы_локал.[Дата резервации])<DateAdd("n",-5,Date()+Time()) 
  Or (Предикторы_локал.[Дата резервации]) Is Null) 
 AND ((Предикторы_локал.Экспорт)=False) 
 AND ((Предикторы_отложенные_локал.[Отложенаня дата])<(Date()+Time())) 
 AND ((Предикторы_отложенные_локал.Звонок_рез_локал) Is Null) 
 AND ((Сессии_активные.Код) Is Null)
)
ORDER BY 
 Предикторы_отложенные_локал.Код_локал DESC , 
 [Предикторы_локал]![Речевой модуль]=[TempVars]![РМ], 
 Предикторы_локал.Приоритет, Предикторы_локал.[Срок отработки], 
 Предикторы_локал.Код;



В третьем запросе мы всегда проверяем резервацию:
Код: sql
1.
2.
((Предикторы_локал.[Дата резервации])<DateAdd("n",-5,Date()+Time()) 
  Or (Предикторы_локал.[Дата резервации]) Is Null)



Однако периодически происходит конфликт, когда два телемаркетолога получают одно и тоже задание в работу.
После Update я запрашиваю идентификатор зарезервированной записи. и создаются связанные записи в таблице звонков.
И телемаркетологу открывается форма с установленным фильтром.

Но, когда оба телемаркетолога получают задание, то происходит следующее:
в предикторах стоит информация о последней резервации.
Разница между двумя актами резервации - 2-3 секунды.

Во всех указанных выше запросах стоит блокировка изменяемой записи.
В аксе (он кстати 2010-й) стоит блокировка на уровне страниц.

При выполнении запроса в ручном режиме, такого конечно не происходит, такое я могу получить только при стресс-тесте системы, когда в один момент два телемаркетолога целенаправленно нажимают на кнопки...

Видимо Update первого телемаркетолога происходит после Select, но до Update второго.

Как Вы решаете вопросы управления очередью задач? Подскажите пожалуйста.
Как быть? Блокировать таблицу? Что здесь вообще происходит?)))
...
Рейтинг: 0 / 0
14.12.2016, 11:13
    #39366502
3 телемаркетолога и Access
...
Рейтинг: 0 / 0
14.12.2016, 11:31
    #39366522
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
ТоликmanКак Вы решаете вопросы управления очередью задач?
Код: sql
1.
2.
3.
4.
5.
6.
7.
update query 
set operator = :op_id
where id in (
              select top 1 id
              from query
              where operator is null
            )

Код: vbnet
1.
sleep 100

Код: sql
1.
2.
3.
select id
from query
where operator = :op_id

Если запись возвращена - резервирование выполнено, обрабатываем. По окончании обработки
Код: sql
1.
2.
3.
update query
set operator = -operator 
where operator = :op_id
...
Рейтинг: 0 / 0
14.12.2016, 11:44
    #39366553
vmag
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
ТоликmanДобрый день!

День сурка?
http://www.sql.ru/forum/1235972/access-lokalnaya-set-i-zapros-na-vyborku?hl=
Я так понимаю обновление DDE не помогло ?

Добавьте галочку в таблицу выбора "занят/свободен"
- на форме висит и обновляется по таймеру список для работы (захвата) со статусом.
- взять в обработку можно только со статусом "свободен".
- после выбора в списке сначала делаем на него принудительно requery (на случай устаревшего статуса) и если статус по прежнему "свободен" - меняем его тут же на "занят" и берем в обработку...
Оставьте в покое эти хлипкие и неуверенные признаки "занят/свободен" (наличие или отсутствие где-то, каких-то записей да еще с признаками...)
...
Рейтинг: 0 / 0
14.12.2016, 12:03
    #39366584
Толикman
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
vmag,

Я хотел сначала ее продолжить, но понял что уже немного другой запрос :)
Автономные файлы выключили везде принудительно, но да, ошибка сохранилась.

Сейчас телемаркетолог не видит список, он просто нажимает "Следующее задание" и ему открывается форма с конкретным заданием.

И я уже так сделал, там прямо в таблице самих задач добавил два поля - Кем зарезервировано и когда.
Обновляю как раз эти поля. И все равно в конфликтных ситуациях происходит обновление одной и той же записи! (((
...
Рейтинг: 0 / 0
14.12.2016, 12:09
    #39366596
Толикman
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
Провел еще один эксперимент:
Установил во всех трех запросах блокировку всей таблицы.

И получил ситуацию - одновременно могут работать только два сотрудника, третий (последний подключившийся) видит ошибку "Таблица заблокирована"...

И блокировка снимается только по факту закрытия всего аксесса любым из первых двух участников.

Таблица входит в блокировку на этапе выполнения соответствующего запроса, а выходит из нее только после закрытия акса.
Видимо, дело в том, что сама таблица также используется в других формах, и поэтому блокировка сохраняется до момента закрытия последней связанной формы - а это главная форма, которая показывает одну цифру: количество доступных задач...
...
Рейтинг: 0 / 0
14.12.2016, 12:14
    #39366602
Толикman
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
Akina,

Два вопроса:

1. Принципиально вложить один запрос в другой прямо в тексте SQL?
Чем это отличается от создания двух запросов в аксе, где первый ссылается на результаты второго?

2. sleep 100? Какие конфликты он должен обойти?
...
Рейтинг: 0 / 0
14.12.2016, 15:02
    #39366888
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
1) Избегаем материализации и получаем атомарность действия.
2) Это типа "демонстрация намерений". На самом деле желательно больше, по максимуму возможного, но чтобы не выпадать из зоны комфорта по скорости работы.

Принципиально здесь - вторым запросом проверить, что при апдейте выбранной записи в неё записаны именно те данные, которые записывались, а не чьё-то ещё поверх. Хотя Акс для таких моментов явно инструмент неподходящий, с его-то файловым контролем блокировок. Желательно использовать полноценный SQL-сервер (а взять хотя бы и СЕ).
...
Рейтинг: 0 / 0
14.12.2016, 15:24
    #39366929
Толикman
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
Akina,

1) я просто думал, что акс при составлении запроса соединяет их в своем движке и только потом выполняет - зря я так думал? Ладно, тогда это может и поможет...
2) А что там файловой блокировкой, я думаю что видимо в ней тоже есть проблема, точнее в моих знаниях об этом... ???

Про сервер - это тонкий ход. Стратегия жестокая конечно же.
Сейчас я хочу показать что в данной маленькой задаче надо перейти к автоматизации.
Некоторое время поработать и показать эффективность персонала.
И после этого инициировать разработку системы на базе нормального сервера, конечно же...
...
Рейтинг: 0 / 0
14.12.2016, 15:57
    #39366982
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
Толикmanзря я так думал?
Угу...

ТоликmanА что там файловой блокировкой
Блокирование в БД Аксесс осуществляется записью информации об объектах блокирования в файл блокировок (.LDB, одноимённый с БД). Так что на самом деле это и не блокирование вовсе, а так... всё чисто "на доверии".
...
Рейтинг: 0 / 0
14.12.2016, 15:59
    #39366989
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
ТоликmanИ после этого инициировать разработку системы на базе нормального сервера, конечно же...Ну так и показывай сразу на базе SQL-сервера. MS SQL Compact Edition для этого вполне подходящая платформа, хотя никто не мешает использовать и другие бесплатные серверы (Firebird, MySQL), благо с драйверами к ним проблем нет. Только настроить всё на выполнение запросов на стороне сервера...
...
Рейтинг: 0 / 0
14.12.2016, 20:22
    #39367187
Толикman
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
Akina,

Я вообще не админ :)
Базу дают на уровне региона, а мне нужен макрорегион. Остальные регионы не получат доступ...
Я бы такие проблемы не испытывал...
...
Рейтинг: 0 / 0
15.12.2016, 11:59
    #39367507
Толикman
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
Блин.

Если запрос выполняется в одну и ту же секунду, то система бронирует одну задачу за несколькими сотрудниками.
Судя по всему проблему в том, что в очередь встает файл с блокировкой...
Надо продумать систему заблаговременной резервации, т.е. вышел на работу, и система зарезервировала тебе на 5 задач вперед.
и управлять это заблаговременной очередью... таким образом перезаписываться будут будущие задачи, а не текущие.

Может есть такой опыт?
...
Рейтинг: 0 / 0
15.12.2016, 12:31
    #39367547
Vladimir Baskakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
если конфликтуют несколько приложений - клиентов, возможно стОит где-то повесить один экземпляр акцесса, который синхронно будет распределять задачи, по таймеру, а остальные - клиентские - только смотреть на результат его деятельности?
...
Рейтинг: 0 / 0
15.12.2016, 12:35
    #39367555
Vladimir Baskakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
просто закронить на машине где база лежит маленький vbs-скриптик, который коннектится и за 5-6 запросов через ADO все распеределяет. Раз 3 секунды. я бы наверное так сделал...
...
Рейтинг: 0 / 0
15.12.2016, 12:44
    #39367565
Толикman
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
Вашу тему можно реализовать по другому - при запуске экземпляра одним из сотрудников - выдать ему право распределять очередь, а все остальные смотрят на его результаты - здесь можно и потратить пару секунд при запуске...
Соответственно создать таблицу, в которой регистрируется этот экземпляр-координатор.
Вот это идея, спасибо!
...
Рейтинг: 0 / 0
15.12.2016, 13:58
    #39367698
Vladimir Baskakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
- мне в этом варианте не нравится, что если он акс срубит, то как бы ой. Но, может как-то додумать до точки и выйдет?
...
Рейтинг: 0 / 0
15.12.2016, 15:57
    #39367896
Толикman
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
Vladimir Baskakov,

Мониторить сессии, у меня запускается фоновая форма, которая раз в 5 минут обновляет дату активности сотрудника.
И есть запрос, который показывает активных сотрудников (дата активносте < 7 минут назад).
Соответственно каждый должен мониторить дату актуализации данного счетчика, как только зависание произошло - стать лидером.

Но я сейчас пробую пока по другому...
Пробую регистрировать в очередь сразу 3 задания.
И каждый раз регитрсировать по три задания (включая обновление ранее зарегитсрированных).
И поменять очередность - сначала привязываем задание, а потом резервируем следующие задания. Таким образом в работу будет поступать задание, которое уже точно ни кем не пере-запишется.
И каждый раз очередь будет на 3 задания вперед.
Таким образом конфликт может быть только при первой регистрации очереди - такой разовый конфликт можно предусмотреть.
Конфликты сами по себе останутся, но они будут происходить по задачам, до которых пользователь еще не дошел - ну как бы да и ладно.
В итоге период синхронизации равен времени отработки одного задания - т.е. с запасом...

При выходе убивать лишнюю резервацию.

Также делать проверку по активным сессиям (если свет вырубило) - если активной сессии нет, а резервация есть - то задачи можно брать в работу...
...
Рейтинг: 0 / 0
15.12.2016, 16:30
    #39367942
Vladimir Baskakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
http://www.sql.ru/forum/1228109/dve-mashiny-edut-po-doroge-s-2-polosami-navstrechu-drug-drugu-kak-im-ne-stolknutsya

так, вспомнилось.

В общем случае, по моему, если надежного механизма лока записей (семафоров) нет - коллизий исключить нельзя. это из параллельного программирования. можно, только чтобы важным делом занимался ровно 1, заранее всем известный, процесс.

Мы можем предлагать - как сделать похожее на лок, за счет флажков, но - логически - коллизии не избежать .... как мне показалось.

Другой вопрос - цена коллизии с т-зр бизнеса? ну позвонят одному клиенту 2 манагера (очень редко почти никогда) -
- может и фиг с ним? ...... у одного будет занято.
...
Рейтинг: 0 / 0
15.12.2016, 21:06
    #39368159
Толикman
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
Vladimir Baskakov,

Vladimir BaskakovДругой вопрос - цена коллизии с т-зр бизнеса? ну позвонят одному клиенту 2 манагера (очень редко почти никогда) - может и фиг с ним? ...... у одного будет занято.

Я тоже на это ставку делал, позвонят раз в месяц и бог с ним...
Каждый день!!! по несколько коллизий!

Там проблема возникает еще у некоторых - обновление в таблицах происходит с задержкой.
Как-будто акс откладывает запрос реальных данных и тянет их из кэша - подключился с тимвивера на оба компа - смотрел в одну и ту же таблицу, данные отличались - в одной с новыми данными, в другой нет (F5 не помогало). Но достаточно было начать вносить данные, как таблица обновлялась и появлялись новые/измененные записи... Здесь я вообще не знаю с чем бороться.
На одном ресурсе решил проблему, там папка реплецировалась на двух зардах. Но на обычном компе такая проблема осталась, хотя автономные файлы выключены везде где можно... Как будто у акса есть свой кэш...

И из-за этого в одном регионе телемаркетологи даже в растянутом по времени диапазоне попадают на одно задание...
...
Рейтинг: 0 / 0
15.12.2016, 21:37
    #39368176
Толикman
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
Тема наверное закрыта.

Это мои кривые руки.
Проблема крылась именно в сессиях.
Некорректно сохранялись активные сессии, тем самым система думала, что сотрудник не работает и выдавала его задачу в работу дргим... Всем спасибо, выработанное решение с очередью на будущее и единым диспетчерским процессом я сохраню в копилку.
...
Рейтинг: 0 / 0
15.12.2016, 23:17
    #39368211
vmag
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
Толикman,

ну раз уж я начал тему, возьми мой пример потестируй на своей сетке (решение по признакам, флажкам или как там...)
имхо теоретически коллизии могут быть, но на практике - думаю не получится у тебя...
- таблицы вынеси в отдельный файл, а к файлу с формой и запросами прилинкуй их на разных машинах...
Описание:
1. Выбираем юзера.
- слева его рабочие заявки (хоть закрывай форму - будут и завтра)
- в середине не обработанные заявки,
- справа выполненные
- кнопки соответствуют спискам над ними.
2. Выбираем в середине заявку, нажимаем Взять заявку в обработку!
Другой юзер (хоть его список старый, уже не сможет эту заявку взять себе).
Ну и тонкости:
- Перед захватом заявки рекомендуется нажать Обновить статус не обработанных заявок.
- можно отменить и взятую заявку и уже обработанную - падают назад в не отработанные...
П.С.
- на код особо не смотри - процентов 50-60 сделано мастерами (кнопки)
- посмотри лучше схему БД - поймешь смысл...
- Изюм: перед пометкой что заявка будет захвачена DLOOK апом проверяется её статус на свободность,
в этом месте тебе будет ОООчень трудно сделать коллизию...
- ну и толком не тестировал, прощай косяки если чё...
...
Рейтинг: 0 / 0
15.12.2016, 23:29
    #39368216
vmag
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
Кстати - вот оно и готовое рабочее место главного менеджера (выше)
- добавить еще один список справа (Все обрабатываемые заявки)...
- а если потом еще прикрутить к форме таймер и мозги - то можно на автомате пихать свалившуюся новую заявку менеджеру, у которого их меньше всего и главный юзер-распределяло уже не нужен ...
...
Рейтинг: 0 / 0
16.12.2016, 06:49
    #39368263
MrShin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
Если речь зашла про многопользовательские приложения, хотелось бы напомнить о механизмах, без знания которых вы будете получать ошибки.
1) это наличие кэша, который по умолчанию обновляется с задержкой. Так что при получении критичных данных нужно кэш обновлять:
Код: vbnet
1.
DBEngine.Idle dbRefreshCache


2) опять же тот же кэш, который не сразу выплевывается на сетевой ресурс, поэтому критичные данные нужно записывать с использованием транзакций примерно так:
Код: vbnet
1.
ws.CommitTrans dbForceOSFlush


3) Блокируем таблицу с критичными данными:
Код: vbnet
1.
Set rs = db.OpenRecordset(TableName, dbOpenTable, dbDenyRead Or dbDenyWrite)


4) Не забываем, что по умолчанию попытка повторно заблокировать ресурс в случае наличия блокировки происходит через 100 милисекунд и может случиться так, что два или более приложения будут пытаться заблокировать ресурс через одно и то же время - соревноваться. Для предотвращения этого в разных экземплярах приложения нужно поменять эту установку на случайное число:
Код: vbnet
1.
DBEngine.SetOption dbLockDelay, 90 + Rnd * 60



Вот здесь это подробно расписано:
https://support.microsoft.com/en-us/kb/191253
...
Рейтинг: 0 / 0
16.12.2016, 08:14
    #39368281
Толикman
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
3 телемаркетолога и Access
MrShinЕсли речь зашла про многопользовательские приложения, хотелось бы напомнить о механизмах, без знания которых вы будете получать ошибки.
1) это наличие кэша, который по умолчанию обновляется с задержкой. Так что при получении критичных данных нужно кэш обновлять:
Код: vbnet
1.
DBEngine.Idle dbRefreshCache


2) опять же тот же кэш, который не сразу выплевывается на сетевой ресурс, поэтому критичные данные нужно записывать с использованием транзакций примерно так:
Код: vbnet
1.
ws.CommitTrans dbForceOSFlush


3) Блокируем таблицу с критичными данными:
Код: vbnet
1.
Set rs = db.OpenRecordset(TableName, dbOpenTable, dbDenyRead Or dbDenyWrite)


4) Не забываем, что по умолчанию попытка повторно заблокировать ресурс в случае наличия блокировки происходит через 100 милисекунд и может случиться так, что два или более приложения будут пытаться заблокировать ресурс через одно и то же время - соревноваться. Для предотвращения этого в разных экземплярах приложения нужно поменять эту установку на случайное число:
Код: vbnet
1.
DBEngine.SetOption dbLockDelay, 90 + Rnd * 60



Вот здесь это подробно расписано:
https://support.microsoft.com/en-us/kb/191253

MrShin, вот за все это огромное спасибо!
...
Рейтинг: 0 / 0
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / 3 телемаркетолога и Access / 25 сообщений из 51, страница 1 из 3
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]