|
v7: Проблемы с блокировками 7.7 | ☑ | ||
---|---|---|---|---|
0
EdGreen
20.02.13
✎
15:33
|
Перевозил базу на новый сервер, пробовал ставить SQL2005 под Win 2003 Делал всякие эксперименты, решил поглядеть на устойчивость блокировок.
Написал совсем простую штуку. В Базе Один справочник с одним полем индексированным, одним бесконечным и одним периодическим. В Глобальном модуле: Процедура Выполнять() Экспорт Спр = СоздатьОбъект("Справочник.Новый1"); Спр.Новый(); Спр.Наименование = ИмяПользователя(); ТекВремя = ТекущееВремя(); Спр.ИндексированныйСтр10 = СокрЛП(ТекВремя); Если Прав(ТекВремя,1) = "7" Тогда Спр.СтрокаНеогр = ТекущееВремя(); КонецЕсли; Спр.ИндексированныйСтр99 = Строка(РабочаяДата())+ТекВремя+РабочаяДата()+ТекВремя+РабочаяДата()+ТекВремя; Состояние(Спр.Код); Спр.Записать(); Спр.Периодический.Установить(РабочаяДата() - Спр.Код,Строка(РабочаяДата() - Спр.Код)); КонецПроцедуры // ВЫполнять ЗаголовокСистемы(ИмяПользователя()); ОбработкаОжидания("Выполнять",1); Что получается: Когда запускаю на Win 2003 в терминале, база под SQL2005, то съедает 70-90% процессора Когда запускаю в своей старой системе Win 2003, так же в терминале под SQL2000, то процессор занят на 3-5% Серверы близки по мощности. Но дальше интересней... Работает совершенно нормально 6-9 одновременно запущенных сессий, но если я начинаю добавлять сессии удалённые, то есть не в терминале запускаю на сервере, а на другом компе по сети, то очень быстро получаю ошибку: Спр.Периодический.Установить(РабочаяДата() - Спр.Код,Строка(РабочаяДата() - Спр.Код)); {Глобальный модуль(16)}: SQL State: 40001 Native: 1205 Message: [Microsoft][ODBC SQL Server Driver][SQL Server]Transaction (Process ID 54) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction Далее ещё интересней.. Запускаю ту же базу на отдельном сервере без SQL Получаю (после 7-8 сессий) Ошибку Код не уникальный. Я понимаю, что тут много разных проблем и причин, я помню как 7.7 нехорошо работает с дедлоками. Однако я не использую никаких средств их разруливания и получаю стопроцентный конфликт. Если кого заинтересовало это, попробуйте на своих системах пожалуйста. Может всё-таки что-то у меня с оборудованием/софтом не так? |
|||
1
Lionee
20.02.13
✎
15:36
|
под SQL2005,не есть айс
|
|||
2
dk
20.02.13
✎
15:44
|
поставь "период ожидания захвата таблицы" в 0 и забудь про блокировки
|
|||
3
ЧеловекДуши
20.02.13
✎
15:52
|
(0)НЕ, у нас все нормально, странно было от тебя не услышать проблему в функции "ВыбратьПодчиненныеДокументы", мы только там споткнулись на 2005-тм :)
А блокировки у нас вырезаются весёлой такой штукой: где ТЗ - это ТаблицаЗначений на форме обработки Перем БазаSQL; Перем DataBase, RecordSet; перем тзРезультат ; Процедура глРедакторТЗ(ТЗ,СписокКолонок="",СписокФормДляОткрытия="", ТекКол="", ТекСтр="") экспорт Перем ВремТЗ ; // врем.таблица для проверки разрешенных для редактирвания колонок ВремТЗ = СоздатьОбъект("ТаблицаЗначений"); Стр = ?(ПустоеЗначение(ТекСтр) = 0,ТекСтр,ТЗ.ТекущаяСтрока()); Кол = ?(ПустоеЗначение(ТекКол) = 0,ТекКол,ТЗ.ТекущаяКолонка()); Если (Число(Стр)=0) или (ПустоеЗначение(Кол)=1) тогда Возврат; КонецЕсли; Значение = ТЗ.ПолучитьЗначение(Стр, Кол); СтароеЗначение = Значение ; // для отмены ТЗ.Выгрузить(ВремТЗ,1,1,СписокКолонок); Если глЕстьКолонкаТЗ(ВремТЗ,Кол)=0 тогда // нельзя редактировать Возврат ; КонецЕсли; Если типзначениястр(СписокФормДляОткрытия)<>"СписокЗначений" Тогда СписокФормДляОткрытия=СоздатьОбъект("СписокЗначений"); КонецЕсли; Тип = ТипЗначенияСтр(Значение); Если Тип="Строка" Тогда Если (СтрДлина(Значение)>50) или (найти(Значение,РазделительСтрок)>0) Тогда Признак=1 ; Иначе Признак=0 ; КонецЕсли; Если ВвестиСтроку(Значение, Кол, 255, признак)<>1 тогда Значение = СтароеЗначение ; КонецЕсли; ИначеЕсли Тип="Число" Тогда Если ВвестиЧисло(Значение, Кол, 20, 4)<>1 тогда Значение = СтароеЗначение ; КонецЕсли; ИначеЕсли Тип="Дата" Тогда Если ВвестиДату(Значение, Кол)<>1 тогда Значение = СтароеЗначение ; КонецЕсли; ИначеЕсли Тип="Перечисление" Тогда Если ВвестиПеречисление(Значение, Кол)<>1 тогда Значение = СтароеЗначение ; КонецЕсли; ИначеЕсли Тип="Справочник" Тогда Попытка ВремСпр = СоздатьОбъект("Справочник."+Значение.Вид()); ВремСпр.НайтиЭлемент(Значение); Если ВремСпр.Выбрать( Кол, СписокФормДляОткрытия.Получить(Кол) )=1 тогда Значение = ВремСпр.ТекущийЭлемент() ; КонецЕсли; Исключение Возврат; КонецПопытки; ИначеЕсли Тип="Документ" Тогда Попытка ВремДок = СоздатьОбъект("Документ."+Значение.Вид()); Если ПустоеЗначение(Значение) = 0 тогда ВремДок.НайтиДокумент(Значение); КонецЕсли; Если ВремДок.Выбрать( Кол, СписокФормДляОткрытия.Получить(Кол) )=1 тогда Значение = ВремДок.ТекущийДокумент() ; КонецЕсли; Исключение Возврат; КонецПопытки; Иначе Если ВвестиЗначение(Значение, Кол)<>1 тогда Значение = СтароеЗначение ; КонецЕсли; КонецЕсли; ТЗ.УстановитьЗначение(Стр, Кол, Значение); КонецПроцедуры //_____________________________________________________________________________ Функция ПодключитьсяКБазе() БазаSQL = 1 ; DataBase = СоздатьОбъект("ODBCDatabase"); Если БазаSQL = 1 Тогда DataBase.Attach1C(); Рез = 1; Иначе Рез = 0 ; КонецЕсли; Если Рез = 0 Тогда Сообщить("Не могу соединиться с базой данных!", "!"); Сообщить(DataBase.GetLastError()); Возврат 0; КонецЕсли; RecordSet = СоздатьОбъект("ODBCRecordSet"); RecordSet.SetDatabase(DataBase); Возврат 1; КонецФункции //_____________________________________________________________________________ Функция ОтключитьсяОтБазы() RecordSet.Close(); DataBase.Close(); RecordSet = ""; DataBase = ""; Возврат 1; КонецФункции //******************************************* Процедура Сформировать() ТекстЗапроса = " | select | text as text, | replace(replace(replace(text,'Create procedure','Alter procedure'), '(TABLOCK HOLDLOCK)',''),'(TABLOCKX HOLDLOCK)','') as newtext | from syscomments where | text LIKE('%(TABLOCK HOLDLOCK)%') or | text LIKE('%(TABLOCKX HOLDLOCK)%') "; Если ПодключитьсяКБазе() = 0 Тогда Возврат; КонецЕсли; ВремяНач = _GetPerformanceCounter(); Состояние("Выполнется запрос"); //Подготовка запроса с проверкой синтаксических ошибок Если RecordSet.Подготовить(ТекстЗапроса) = 0 Тогда Сообщить(RecordSet.GetLastError(), "!"); Сообщить(ТекстЗапроса, "I"); Перейти ~Завершение; КонецЕсли; тзРезультат = СоздатьОбъект("ТаблицаЗначений"); //Выполним запрос, и запихнем результаты в ТЗ Попытка RecordSet.Open(); ТекстИнфо = "Выполнение - " + (_GetPerformanceCounter() - ВремяНач) + "мс"; Состояние("Выгружается результат запроса"); RecordSet.GetResultsInVT(тзРезультат, 1); ТекстИнфо = ТекстИнфо + "; Общ. время - " + (_GetPerformanceCounter() - ВремяНач) + "мс; "+тзРезультат.КоличествоСтрок()+" строк."; Форма.Инфо.Заголовок(ТекстИнфо); Состояние("Подготовка к показу таблицы запроса"); Исключение Сообщить(RecordSet.GetLastError()); Сообщить(ТекстЗапроса); КонецПопытки; тзРезультат.Выгрузить(ТЗ) ; Форма.Обновить(); тзРезультат.ВыбратьСтроки(); Пока тзРезультат.ПолучитьСтроку()=1 Цикл RecordSet.Выполнить(тзРезультат.newtext) ; КонецЦикла; // конец тзРезультат.ПолучитьСтроку() ~Завершение: ОтключитьсяОтБазы(); КонецПроцедуры |
|||
4
EdGreen
20.02.13
✎
16:12
|
(3) Текст красивый. Но я пока не ищу способа, как решить эту проблему. Я, пока только, пытаюсь её понять.
Если бы у меня возникали конфликты блокировки только под SQL2005, я бы даже не поднимал эту тему. Но аналогичные проблемы, разве что при большей нагрузке, у меня вылезли и под SQL2000 и в DBF. Вот тут мне уже совсем непонятно. Как вообще эта система может работать, если дедлок возникает на совсем простом примере в 100% случаях. У меня уже параноидальное предположение, что я когда-то давно играясь с вариантами решения проблемы дедлоков что-то пропатчил и забыл. |
|||
5
EdGreen
20.02.13
✎
17:10
|
Во всей этой истории меня больше всего прибивает вот это:
Спр.Записать(); {Глобальный модуль(11)}: Код не уникальный! Вот такого вообще быть не должно, мне кажется! |
|||
6
sapphire
20.02.13
✎
17:31
|
(1) Да нормально всё там, не гони :)
|
|||
7
sapphire
20.02.13
✎
17:32
|
(3) Садист :)
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |