Извечная проблема. Ошибка после динамического обновления (SQL)
Вдаваться в подробности, что такое динамическое обновления, как оно полезно и как оно вредно я не буду, так как статей на эту тему уже много, так же как и способов ее решения. Просто расскажу о своем опыте и о требовании для разработчиков 1С, которое было введено в компании на основе этого опыта.
- Описание
- Подробнее
Описание
Динамическое обновление — это, конечно, нехорошо, но порой других возможностей просто нет. К примеру, компания, работающая 24/7 с количеством людей, работающих в базе, от 100 человек. Когда всех выгнать из базы и провести обновление очень затратно и необходимо заранее это согласовывать, тогда приходится использовать динамическое обновление. Сама ошибка заключется в том, что в момент записи в таблицу «Config» что-то произошло, что помешало корректно закончить данную процедуру. И существует два основных способа лечения этой проблемы:
— Первый — это удалить записи о том, что конфигурация обновлялась (не рекомендую, так как у меня не всегда корректно работало).
— Второй способ — перезаписать все данные в таблицы «Config» из резервной копии вашей рабочей базы.
Второй способ более надежный, но была проблема в том, что необходимо было поднимать и разворачивать SQL-ный бэкап, что занимало много времени.
И поэтому придумали простой и надежный механизм. Перед каждым динамическим обновлением просто сохранять таблицы «Config» и «ConfigSave» (Сохранять ConfigSave» не обязательно, мы делали, чтобы сохранить сделанные наработки в конфигурации).
Создал внешнюю обработку с двумя кнопками «Сохраниться перед динамическим обновлением» и «Восстановить данные после ошибки динамического обновления».
Копка «Сохраниться перед динамическим обновлением» вызывает процедуру:
Процедура Сохраниться()
//Подключение к SQL
Connection=Новый COMОбъект("ADODB.Connection");
Connection.ConnectionTimeOut =600;
Connection.Open("Provider=SQLOLEDB.1;Password=Пароль;Persist Security Info=True;User ID=Пользовать;Initial Catalog=SQL_ИмяБазы;Data Source=SQL_Сервер");
RecordSet=Новый COMОбъект("ADODB.Recordset");
RecordSet.CursorLocation=3;
RecordSet.LockType=2;
Запрос="[master].[dbo].[sp_backup_config_tables]";
RecordSet.Open(Запрос, Connection);
//Сохраняем информацию о последнем обновлении
СтруктураДанных=Новый Структура();
СтруктураДанных.Вставить("Пользователь",ПараметрыСеанса.ТекущийПользователь);
СтруктураДанных.Вставить("ДатаСохранения",ТекущаяДата());
СтруктураДанных.Вставить("ИмяСервера",ИмяКомпьютера());
ЗначениеВФайл (ПолноеИмяФайла,СтруктураДанных);
ТекстИзменений="";
Запрос="SELECT [FileName] FROM [SQL_ИмяБазы].[dbo].[ConfigSave]";;
RecordSet.Open(Запрос, Connection);
Если RecordSet.RecordCount>0 Тогда
RecordSet.MoveFirst();
Пока НЕ RecordSet.EOF() Цикл;
ТекстИзменений=ТекстИзменений+Символы.ПС+строка(RecordSet.Fields(0).Value);
RecordSet.MoveNext();
КонецЦикла;
КонецЕсли;
RecordSet.Close();
Сообщить("Данные сохранены. Будут изменены таблици:"+ТекстИзменений);
КонецПроцедуры
Копка «Восстановить данные после ошибки динамического обновления» вызывает процедуру:
Процедура Восстановить ()
//Подключение к SQL
Connection=Новый COMОбъект("ADODB.Connection");
Connection.ConnectionTimeOut =6000;
Connection.Open("Provider=SQLOLEDB.1;Password=Пароль;Persist Security Info=True;User ID=Пользовать;Initial Catalog=SQL_ИмяБазы;Data Source=SQL_Сервер");
Command = Новый COMОбъект("ADODB.Command");
Command.ActiveConnection = Connection;
Command.CommandText ="[master]. [dbo].[sp_restore_config_tables]";
Command.CommandType = 1;
RecordSet = Новый ComОбъект("ADODB.RecordSet");
RecordSet.CursorType = 3;
RecordSet.LockType = 2;
RecordSet = Command.Execute();
КонецПроцедуры
[master].[dbo].[sp_backup_config_tables] и [master]. [dbo].[sp_restore_config_tables]
Это процедуры в SQl.
[master].[dbo].[sp_backup_config_tables]
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
/*
** The system profile of the same type of agent will be used as a template for
** the parameters in this new user profile.
*/
ALTER procedure [dbo].[sp_backup_config_tables]
AS SET NOCOUNT ON
truncate table [dbo].[Config_Backup];
truncate table [dbo].[ConfigSave_Backup];
insert into [dbo].[Config_Backup]
select * from SQL_ИмяБазы.[dbo].[Config];
insert into [dbo].[ConfigSave_Backup]
select * from SQL_ИмяБазы.[dbo].[ConfigSave];
[master]. [dbo].[sp_restore_config_tables]
USE [master]
GO
/****** Object: StoredProcedure [dbo].[sp_restore_config_tables] Script Date: 01/22/2015 11:48:09 ******/
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
/*
** The system profile of the same type of agent will be used as a template for
** the parameters in this new user profile.
*/
ALTER procedure [dbo].[sp_restore_config_tables]
AS
SET NOCOUNT ON
truncate table SQL_ИмяБазы.[dbo].[Config];
truncate table SQL_ИмяБазы.[dbo].[ConfigSave];
insert into SQL_ИмяБазы.[dbo].[Config]
select * from [dbo].[Config_Backup];
insert into SQL_ИмяБазы.[dbo].[ConfigSave]
select * from [dbo].[ConfigSave_Backup];
При нажатии кнопки «Восстановить данные после ошибки динамического обновления» блокировать работу пользователей не надо. Те, которые уже работают, ничего не заметят, а новые зайти не смогут.
Если раньше такая ошибка считалась критичной и время восстановления занимало до 1 часа, то теперь оно сократилось до 5 минут.
Update :
Статья о триггере , для сохранения таблицы Config перед обновлением //sale.itcity.ru/public/327674/