|
248 | 248 | // Проверяет многопоточную работу менеджера сущностей в режиме фоновых заданий |
249 | 249 | &Тест |
250 | 250 | Процедура МногопоточнаяРаботаСФоновымиЗаданиями() Экспорт |
251 | | - // Проверяем доступность API фоновых заданий |
252 | | - |
253 | | - ДоступныФоновыеЗадания = Ложь; |
254 | | - Попытка |
255 | | - Если ТипЗнч(ФоновыеЗадания) = Тип("МенеджерФоновыхЗаданий") Тогда |
256 | | - ДоступныФоновыеЗадания = Истина; |
257 | | - КонецЕсли; |
258 | | - Исключение |
259 | | - // API фоновых заданий недоступен |
260 | | - КонецПопытки; |
261 | | - |
262 | | - Если НЕ ДоступныФоновыеЗадания Тогда |
263 | | - Сообщить("API фоновых заданий недоступен. Выполняем симуляцию многопоточности."); |
264 | | - ВыполнитьСимуляциюМногопоточности(); |
265 | | - Возврат; |
266 | | - КонецЕсли; |
267 | 251 |
|
268 | 252 | // Создаем менеджер с пулом соединений для тестирования |
269 | 253 | ТипКоннекторы = ТипЗнч(МенеджерСущностей.ПолучитьКоннектор()); |
|
297 | 281 | КонецЦикла; |
298 | 282 |
|
299 | 283 | // Ждем завершения всех фоновых заданий (максимум 10 секунд) |
300 | | - СчетчикОжидания = 0; |
301 | | - Пока СчетчикОжидания < 100 Цикл |
302 | | - ВсеЗавершены = Истина; |
303 | | - Для Каждого Задание Из МассивЗаданий Цикл |
304 | | - Если Задание.Состояние = СостояниеФоновогоЗадания.Активно Тогда |
305 | | - ВсеЗавершены = Ложь; |
306 | | - Прервать; |
307 | | - КонецЕсли; |
308 | | - КонецЦикла; |
309 | | - |
310 | | - Если ВсеЗавершены Тогда |
311 | | - Прервать; |
312 | | - КонецЕсли; |
313 | | - |
314 | | - Приостановить(100); // 100 мс |
315 | | - СчетчикОжидания = СчетчикОжидания + 1; |
316 | | - КонецЦикла; |
| 284 | + ОжидатьЗавершенияВсехЗаданий(МассивЗаданий, 100, 100); |
317 | 285 |
|
318 | 286 | // Фиксируем транзакцию основного потока |
319 | 287 | МенеджерСПулом.ЗафиксироватьТранзакцию(ОсновнойКонтекстID); |
|
345 | 313 | МенеджерСПулом.Закрыть(); |
346 | 314 | КонецПроцедуры |
347 | 315 |
|
348 | | -// Симуляция многопоточности когда API фоновых заданий недоступен |
349 | | -Процедура ВыполнитьСимуляциюМногопоточности() |
350 | | - // Создаем несколько независимых контекстов для имитации многопоточности |
351 | | - ТипКоннекторы = ТипЗнч(МенеджерСущностей.ПолучитьКоннектор()); |
352 | | - МенеджерСПулом = Новый МенеджерСущностей( |
353 | | - ТипКоннекторы, |
354 | | - СтрокаСоединенияКоннектора, |
355 | | - Неопределено, |
356 | | - 3 |
357 | | - ); |
358 | | - МенеджерСПулом.ДобавитьКлассВМодель(Тип("Автор")); |
359 | | - МенеджерСПулом.Инициализировать(); |
360 | | - |
361 | | - // Имитируем параллельную работу нескольких "потоков" |
362 | | - МассивКонтекстов = Новый Массив; |
363 | | - |
364 | | - // "Поток" 1 |
365 | | - КонтекстID1 = МенеджерСПулом.НачатьТранзакцию(); |
366 | | - МассивКонтекстов.Добавить(КонтекстID1); |
367 | | - |
368 | | - Автор1 = Новый Автор; |
369 | | - Автор1.Имя = "Поток1"; |
370 | | - Автор1.ВтороеИмя = "Симуляция"; |
371 | | - МенеджерСПулом.Сохранить(Автор1, КонтекстID1); |
372 | | - |
373 | | - // "Поток" 2 |
374 | | - КонтекстID2 = МенеджерСПулом.НачатьТранзакцию(); |
375 | | - МассивКонтекстов.Добавить(КонтекстID2); |
376 | | - |
377 | | - Автор2 = Новый Автор; |
378 | | - Автор2.Имя = "Поток2"; |
379 | | - Автор2.ВтороеИмя = "Симуляция"; |
380 | | - МенеджерСПулом.Сохранить(Автор2, КонтекстID2); |
381 | | - |
382 | | - // "Поток" 3 с ошибкой |
383 | | - КонтекстID3 = МенеджерСПулом.НачатьТранзакцию(); |
384 | | - МассивКонтекстов.Добавить(КонтекстID3); |
385 | | - |
386 | | - Автор3 = Новый Автор; |
387 | | - Автор3.Имя = "Поток3"; |
388 | | - Автор3.ВтороеИмя = "СОшибкой"; |
389 | | - МенеджерСПулом.Сохранить(Автор3, КонтекстID3); |
390 | | - |
391 | | - // Фиксируем первые два, третий откатываем |
392 | | - МенеджерСПулом.ЗафиксироватьТранзакцию(КонтекстID1); |
393 | | - МенеджерСПулом.ЗафиксироватьТранзакцию(КонтекстID2); |
394 | | - МенеджерСПулом.ОтменитьТранзакцию(КонтекстID3); // Имитируем ошибку |
395 | | - |
396 | | - // Проверяем результат |
397 | | - Результат = МенеджерСПулом.ПолучитьКоннектор().ВыполнитьЗапрос("SELECT * FROM Авторы ORDER BY Имя"); |
398 | | - Ожидаем.Что(Результат, "Должны сохраниться только успешные операции").ИмеетДлину(2); |
399 | | - Ожидаем.Что(Результат[0].Имя, "Первый автор").Равно("Поток1"); |
400 | | - Ожидаем.Что(Результат[1].Имя, "Второй автор").Равно("Поток2"); |
401 | | - |
402 | | - МенеджерСПулом.Закрыть(); |
| 316 | +// Ожидать завершения всех переданных фоновых заданий |
| 317 | +// |
| 318 | +// Параметры: |
| 319 | +// Задания - Массив - Массив фоновых заданий (объекты типа ФоновоеЗадание) |
| 320 | +// МаксИтераций - Число - Максимальное количество итераций ожидания |
| 321 | +// ИнтервалМС - Число - Пауза между итерациями в миллисекундах |
| 322 | +Процедура ОжидатьЗавершенияВсехЗаданий(Задания, МаксИтераций, ИнтервалМС) |
| 323 | + СчетчикОжидания = 0; |
| 324 | + Пока СчетчикОжидания < МаксИтераций Цикл |
| 325 | + ВсеЗавершены = Истина; |
| 326 | + Для Каждого Задание Из Задания Цикл |
| 327 | + Если Задание.Состояние = СостояниеФоновогоЗадания.Активно Тогда |
| 328 | + ВсеЗавершены = Ложь; |
| 329 | + Прервать; |
| 330 | + КонецЕсли; |
| 331 | + КонецЦикла; |
| 332 | + Если ВсеЗавершены Тогда |
| 333 | + Прервать; |
| 334 | + КонецЕсли; |
| 335 | + Приостановить(ИнтервалМС); |
| 336 | + СчетчикОжидания = СчетчикОжидания + 1; |
| 337 | + КонецЦикла; |
403 | 338 | КонецПроцедуры |
404 | 339 |
|
| 340 | + |
405 | 341 | // Процедура для выполнения в фоновом задании |
| 342 | +// Создание автора в отдельной транзакции (используется в тестах фоновых заданий) |
| 343 | +// Параметры: |
| 344 | +// ПараметрыЗадания - Структура - Данные для выполнения (МенеджерСущностей, НомерЗадания) |
406 | 345 | Процедура ФоновоеЗаданиеСозданияАвтора(ПараметрыЗадания) Экспорт |
407 | 346 | МенеджерСущностей = ПараметрыЗадания.МенеджерСущностей; |
408 | 347 |
|
|
425 | 364 | КонецПроцедуры |
426 | 365 |
|
427 | 366 | // Процедура для выполнения в фоновом задании с пулом соединений |
| 367 | +// Создание автора при активном пуле соединений (используется в тестах) |
| 368 | +// Параметры: |
| 369 | +// ПараметрыЗадания - Структура - Данные для выполнения (МенеджерСущностей, НомерЗадания) |
428 | 370 | Процедура ФоновоеЗаданиеСозданияАвтораСПулом(ПараметрыЗадания) Экспорт |
429 | 371 | МенеджерСущностей = ПараметрыЗадания.МенеджерСущностей; |
430 | 372 | НомерЗадания = ПараметрыЗадания.НомерЗадания; |
|
0 commit comments