|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
Есть сетевая база данных (по гражданам) в VFP9.0. Есть в ней поле, будем называть его порядковый номер и он должен быть распечатан в бланке. Есть таблица ss, расположенная не в базе данных, т.е. отдельно. Из одной записи, в которой указан последний номер по порядку. При добавлении в базу нового человека, система прописывает в поле "порядковый номер" значение+1 из таблицы ss и при нажатии на клавишу "Сохранить" кроме смысловых проверок по всем полям, происходит поиск по всей базе этого значения (на отсутствие дубля) и если дубля нет, то происходит добавление новой записи в БД. Если несколько операторов добавлябт в БД собственную запсись (разных граждан) , то и у одного и др.оператора в разных карточках людей система показывает в поле "порядковый номер" одно и то же значение (из таблицы ss+1) .Если нажимают на клавишу "Сохранить" не в одну секунду, то система порядковый номер последнему нажавшему меняет автоматически, т.е. может присвоить не только на +1, но и вычислит последний, который прописался в ss (это может быть и +2, +3 - все с разной скоростью работают). Но если нажать на кл."Сохранить" в одну секунду обоим операторам, то получается дубль по порядковому номеру. Сразу скажу, что построить уникальный ключ по этому номеру в БД нельзя по определённым причинам (из-за старых наследуемых данных). Задача - чтобы при многопольз.работе порядковй номер не дублировался. Думали, что FOX сам отследит... Как грамотно эту проблему решить? Пробовать перед SEEK по БД ставить flock и освободить файл только после сохранения -поставить unlock? Может какие-то др.варианты решения есть? ответ нужен срочно, т.к. в БД уже попали дубли и нужно внести изменения впрогу ... |
|||
:
Нравится:
Не нравится:
|
|||
20.09.2010, 11:50 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
Поиск по NewID ... |
|||
:
Нравится:
Не нравится:
|
|||
20.09.2010, 12:17 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
songv, таблица СС должна быть заблокирована (вся или одна запись) с момента ее чтения юзером и до тех пор, пока номер клиента не будет записан в таб. клиентов. Если будет работать, то снимите поиск двойников по этому полю. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.09.2010, 13:29 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
igorbik, поиск двойников не могу снять из-за наследуемых данных в БД (такие записи ранее были и они должны, увы, сохраниться в БД) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.09.2010, 14:36 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
songvigorbik, поиск двойников не могу снять из-за наследуемых данных в БД (такие записи ранее были и они должны, увы, сохраниться в БД)При таком наследстве, и учитывая, что двойников быть не должно, я бы поступил так: 1) если нет желания отказываться от таблицы SS, то найти максимальный номер клиента на сегодня и продолжить нумерацию с этого номера 2) если без SS (так у меня сделано), то примерно так: а) блокируем всю таблицу с гражданами. Тогда в это время никто с ней ничего не сделает, разве что прочитать можно. б) ищем макс. номер и наращиваем его на единицу в) вставляем новую запись и вписываем туда этот номер г) разблокируем таблицу. Теперь любой другой юзер не запишет тот же номер. В Инете есть много примеров, ищИте. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.09.2010, 15:51 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
igorbik, так всё и делается. если разница по времени несколько секунд между сохранением у разных операторов. Как только одновременно, в одну секунду - хоть тресни, дубль ... |
|||
:
Нравится:
Не нравится:
|
|||
20.09.2010, 16:47 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
songv, причин может быть очень много, начиная с того, что все-таки не совсем так все сделано, и заканчивая хромым железом, софтом и сетью. Попробуйте еще поиграться с параметрами блокировки (посмотрите в хелпе раздел "Блокировка данных", "Программирование многопользовательского доступа" и пр.) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.09.2010, 18:10 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
Имеется некая таблица (у меня MISC,DBF), в ней поле типа LASTNUM (N). Надо добавить запись - Код: plaintext 1. 2. 3. 4. 5.
Код: plaintext 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. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.09.2010, 20:56 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
reware, у нас таблицы уже открыты, ничего открывать не нужно. Подозрение на то, что не успевает индекс обновиться по этому полю в таблице по гражданам, поэтому прога не видит, что этот номер уже записался ... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 10:47 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
У Вас среди старых данных может существовать значение, которое еще только будет сформировано в таблице SS? Т.е. сам по себе генератор может создавать дубли? Если такого быть не может, то, очевидно, что дело не в индексе, а в не корректном разрешении конфликтов совместного доступа. Логика примерно такая - Первый пользователь нашел нужную запись в таблице SS и считал текущее значение - Второй пользователь в то же самое время нашел эту же самую запись в таблице SS и считал то же самое значение - Первый пользователь увеличил счетчик - Второй пользователь "увеличил" счетчик, но по сути, оставил его без изменений Как разрешить подобный конфликт? Очевидно, что считывать значение счетчика надо не ДО, а ПОСЛЕ установки блокировки. Т.е. логика становится примерно такая Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
Разумеется, это всего-лишь общая схема. Тут еще надо кучу проверок сделать. Все-таки, воспользуйтесь поиском по данному сайту по ключевому слову "NEWID". Как написать этот код корректно много раз обсуждалось. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 11:29 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
Попробуй сойти с записи непосредственно после replace (go recno) ... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 11:41 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
songv Задача - чтобы при многопольз.работе порядковй номер не дублировался. Думали, что FOX сам отследит... версия фокспро? у фокспро есть возможность создать автоинкриментн.счетчик. чем он Вас не устроил? Код: plaintext 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 11:56 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
ВладимирМ, именно так и делаем. как думается, дело не в таблице ss (последний выданный номер). А в том, что когда запись с этим номером попадает после работы первого оператора в таблицу с гражданами, повторная проверка на уникальность по этой уже таблице не отрабатывается при сохранении вторым оператором новой записи с др.гражданином - за 1 сек. Как будто система не видит (не успевает увидеть), что уже первый оператор добавил запись с новым номером. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 14:29 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
прошелмимо, естественно, что id есть и присваивается уникальным. Но этот номер - не есть id. Он в некоторых случаях может корректироваться оператором, поэтому дубль может возникнуть не только по последнему введённому номеру, но и по номеру, существующему в БД, внесённому ранее. Представьте себе несколько пунктов, которые выдают гражданам определённые бланки, и каждому пункту из центра даётся определённый диапазон номеров. Т.Е. через какой-то временной интервал может следующий бланк быть с номером, не следующим по порядку за предыдущим, а с совершенно новым, и последующие номера на бланках должны распечатываться с +1 от этого нового номера. Да + к этому "старое наследство" записей, закаченных в систему, где дубли по номеру были. поэтому индекс кандидат на этом поле нельзя сделать ... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 14:36 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
songvпрошелмимо, естественно, что id есть и присваивается уникальным. Но этот номер - не есть id. Он в некоторых случаях может корректироваться оператором, поэтому дубль может возникнуть не только по последнему введённому номеру, но и по номеру, существующему в БД, внесённому ранее. Представьте себе несколько пунктов, которые выдают гражданам определённые бланки, и каждому пункту из центра даётся определённый диапазон номеров. Т.Е. через какой-то временной интервал может следующий бланк быть с номером, не следующим по порядку за предыдущим, а с совершенно новым, и последующие номера на бланках должны распечатываться с +1 от этого нового номера. Да + к этому "старое наследство" записей, закаченных в систему, где дубли по номеру были. поэтому индекс кандидат на этом поле нельзя сделать изв., меня учить не нужно - я работаю с САП и разрабатываю на АБАП. (а то начну плеваться и матюгаться) у меня для этого дела есть интегрированные в "словарь" диапазоны. в вашем случае - самое простое - это ипользовать фоксовый автоинкримент. в противном случае - создать подобный нумератор посредством создания таблички с полем-запоминателем последнего номера. номер вводить не давать, а присваивать в момент сохр-я, блокируя и передергивая счетчик. какой-то пример могу сваять. в принципе такой нумератор при опред-м способе разработки может быть универсальным и применяться для создяания сложных номеров с аналит.признаками аля: 01-сент-001 01-сент-002 01-сент-002 ... 02-сент-001 ... ... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 14:47 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
songvВладимирМ, именно так и делаем. как думается, дело не в таблице ss (последний выданный номер). А в том, что когда запись с этим номером попадает после работы первого оператора в таблицу с гражданами, повторная проверка на уникальность по этой уже таблице не отрабатывается при сохранении вторым оператором новой записи с др.гражданином - за 1 сек. Как будто система не видит (не успевает увидеть), что уже первый оператор добавил запись с новым номером. Еще раз. Если сам генератор сконструирован таким образом, что исключает генерацию одинаковых значений разными пользователями (пусть они и "одновременно" обращаются за новым значением), то дополнительная проверка на уникальность - это перестраховка, в общем-то, особо и не нужная. Проблема-то не в том, что индекс там успевает или не успевает, а в том, что программа сгенерила одинаковые значения. То, что не сумели потом пресечь их использование - это другой разговор (думаю, проще сделать индекс CANDIDATE с for-условием). Это уже следствие, а не причина. Также мне кажется, что дело не в обновлении индекса, а в том, что на момент проверки никакого дубля и не было. Ну, не успел еще второй пользователь что-то там записать, просто физически нет дубля. Опять возвращаемся к тому, с чего начали - уникальность должен обеспечивать сам генератор значений, а не последующая проверка. Попробуйте еще такой фокус Код: plaintext 1. 2. 3. 4.
Фиктивный переход на ту же самую запись позволяет обновить буфер этой записи. Возможно, при "одновременной" генерации тот пользователь, который сидит на Reprocess в команде RLOCK() "не видит" изменений, сделанных другим пользователем/ ... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 14:47 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
songvестественно, что id есть и присваивается уникальным. Но этот номер - не есть id. Он в некоторых случаях может корректироваться оператором, поэтому дубль может возникнуть не только по последнему введённому номеру, но и по номеру, существующему в БД, внесённому ранее. Вот оно в чем дело. Т.е. генератор значений предлагает некое значение, а затем пользователь может его скорректировать. И рассматриваем ситуацию, когда два пользователя "одновременно" ввели два одинаковых значения. Ну, в этом случае генератор значений вообще никакого отношения не имеет к обсуждаемой проблеме. Представьте себе, что два пользователя "одновременно" дали команду на вставку Код: plaintext
Никакие внешние проверки ничего не смогут противопоставить возникновению подобного "дубля". Ведь оба пользователя сделали проверки ДО собственно вставки. Когда ни один из них еще ничего физически не вставил. Действительно, не было дубля. - Первый пользователь проверил - нет дубля - Второй пользователь проверил - нет дубля, поскольку первый еще ничего не вставил - Первый пользователь вставил - Второй пользователь вставил - получили дубль Подобные дубли можно отловить только на уровне контроля базы данных следующими способами 1. Индекс Candidate/Primary. Возможно, с for-условиями 2. Триггер на вставку (но это если таблица включена в контейнер базы данных) ... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 14:57 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
songv Как будто система не видит (не успевает увидеть), что уже первый оператор добавил запись с новым номером. ок. покажите как Вы добавляете записи в табличку. я бы сделал прибл. так: 1. поднял курсорадаптер с условием фолс 2. добавил в курсорадаптер новую запись 3. автоматом вычислил новый номер (возможен и хитрый алгоритм по возможным диапазонам для какой-то группы пользователей) 4. сохранил изменения в основную таблицу-источник (возможно применив какой-то алгоритм, который сработает со стороны БД - если уж так "вкрай" необходимо отсутствие дублей) и не давал-бы возможности руками править этот номер. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 15:10 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
ВладимирМ, вы всё правильно поняли. первый предложенный вами вариант (с кандидатом)не подходит. А второй - не очень понятно, что вы имеете ввиду? Мы сейчас увидели такой сюжет в трейси. Когда сами программно заблокировали таблицу от вставки записи - программа сняла автоматически блокировку (это произошло при генерации primery ключа для главной таблицы базы данных) . Ну и понятно, что дальше понятие блокировки уже отсутствует. Праймери ключом является guid. Похоже, что формирование ключа сбивает блокировку. Ничего не получается, блин ... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 16:14 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
Во нахреначили! ... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 16:16 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
ПЗРК0012, это не мы, это законы такие дурацкие, что под них проги нельзя адеквтные, нормализованные писать ... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 16:25 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
Не мое, но это то что Вам нужно. Привет Благовещенску. Код: plaintext 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. 38. 39. 40. 41. 42. 43. 44. 45.
... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 16:33 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
songvВладимирМ, вы всё правильно поняли. первый предложенный вами вариант (с кандидатом)не подходит. Почему? Ведь в FOR-условии можно просто отсечь все "архивные" данные, написав условие, например, больше какого-то значения. Впрочем, Вам виднее songvА второй - не очень понятно, что вы имеете ввиду? Если таблица включена в контейнер базы данных, то в режиме дизайнера таблицы будет доступна закладка Table. Там есть группа полей "Triggers", где можно написать вызов функций при возникновении событий вставки/изменения/удаления записи. Подробнее про триггер здесь Триггер Тут "фишка" в том, что на момент срабатывания триггера все значения всех полей текущей записи (в FoxPro триггер обрабатывает изменения всегда только одной записи) уже сформированы, запись заблокирована, но пока еще эти изменения не сброшены в таблицу. Вот тут-то и можно запустить проверку уникальности. Если очень надо, могу привести пример подобного триггера. songvМы сейчас увидели такой сюжет в трейси. Когда сами программно заблокировали таблицу от вставки записи - программа сняла автоматически блокировку (это произошло при генерации primery ключа для главной таблицы базы данных) . Ну и понятно, что дальше понятие блокировки уже отсутствует. Праймери ключом является guid. Похоже, что формирование ключа сбивает блокировку. Ничего не получается, блин Ну, это Вы разбирайтесь со своим кодом, почему у Вас происходит сброс блокировок. Скорее всего, Вы используете UNLOCK без указания записи, с которой надо снять блокировку. В этом случае действительно блокировка сниматся со всех записей. Это я к тому, что в описанной ситуации - однозначно не корректный код по установке/снятию блокировок. Причем именно код на FoxPro. API-функции генерации GUID тут явно не при чем. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 20:17 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
Да, на чем основана уверенность, что "тригер не пропустит". Если таблица имеет индексный тег по контролируемому полю (любой индекс, достаточно обычного Regular) и все это выполняется внутри транзакции, то на момент выполнения транзакции файл индекса будет блокирован для модификции. Весь файл индекса . Как следствие, пока не будет закрыта или отменена транзакция никто не сможет изменить те поля, по которым построен индекс ни в одной записи. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.09.2010, 20:33 |
|
нужна блокировка!!!
|
|||
---|---|---|---|
#18+
ВладимирМНу, это Вы разбирайтесь со своим кодом, почему у Вас происходит сброс блокировок. Скорее всего, Вы используете UNLOCK без указания записи, с которой надо снять блокировку. В этом случае действительно блокировка сниматся со всех записей. возможно там происходит "топтание" по записи основной таблицы и куча реплейсов. в фокспро можно работать с основной таблицей через буфер посредством курсорадаптера. в таком буфере можно подготовить новую запись и "топтаться" по ней сколько угодно, а затем одним махом положить такую новую запись в основную таблицу. использование КАДа в таком случае облегчает разработку и оберегает от ряда подобных коллизий. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.09.2010, 09:14 |
|
|
start [/forum/topic.php?fid=41&fpage=89&tid=1584934]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
30ms |
get topic data: |
12ms |
get forum data: |
2ms |
get page messages: |
136ms |
get tp. blocked users: |
2ms |
others: | 16ms |
total: | 227ms |
0 / 0 |