Автор: Андрей Волков
Commit Record. Казалось бы – элементарная вещь. Но в формате небольшой заметки про нее не расскажешь.
Потому что невозможно говорить о команде FileMaker Commit Record и оставить без внимания команды Open Record, Revert Record. Придется упомянуть события и триггеры (OnRecordCommit ), функции Get(RecordOpenState) и Get(RecordOpenCount). Слегка или глубоко коснуться различий в однопользовательском и многопользовательском подключениях. И пару слов сказать о назначении команды Flash cash to disk.
А начну совсем издалека.
Когда пользователь работает с базой данных, то те записи, которые он наблюдает – это не оригинальные записи таблиц файла базы данных. А их копии. Копии, снимки, которые создаются, когда пользователь подгружает базу данных и начинает перемещаться по записям. Можно образно сказать, что каждый пользователь работает со своим индивидуальным слепком базы данных.
С этим слепком он может делать все, что захочет. Но, строго говоря, поведение приложения FileMaker будет зависеть от того, что он, пользователь, делает. Если пользователь только просматривает данные, ничего не меняя в них, то FileMaker никак на это не реагирует. Но как только пользователь попытается внести хоть малейшее изменение в данные, произойдет событие Open Record, при котором:
Приложение запросит у сервера, не является ли редактируемая запись заблокированной. Если она не заблокирована, то пользователю будет разрешено продолжить редактирование. При этом сервер получает уведомление о том, что определенная запись редактируется, и блокирует ее для всех остальных пользователей.
Запись может редактироваться только одним пользователем и только в одном окне.
Напомним, что пользователь вносит изменения не в саму запись БД, но в ее клон, созданный приложением, в котором он работает. И если он хочет, чтобы изменения записались в базу данных, он вызывает событие, называемое Commit. При завершении этого события запись в базе данных обновляется (UPDATE), с нее снимается блокировка, все подключенные к серверу приложения получают информацию об изменении базы данных, происходит процесс обновления экрана на уровне каждого открытого пользовательского приложения (то есть другие пользователи тоже видят изменения). Событие Commit также снимает фокус с любых объектов.
Вызвать событие Open Record («Открыть Запись») можно программно: командой Open Record или любыми командами, создающими записи или изменяющими текущую запись: команды редактирования, Set Field, Insert и т.п. Но вообще оно возникает, когда пользователь создает новую запись или пытается редактировать существующую. Не «открываются» записи при редактировании глобальных полей и использовании массовых обработок – команд Replace Field Contents, Relookup Field Contents, Import Records (update). Во время выполнения этих команд каждая измененная запись сохраняется автоматически, перехватить и отменить действие этих команд невозможно.
При «открытии» статус редактируемой записи изменится, это можно определить функцией Get(RecordOpenState). Функция Get(RecordOpenCount), покажет количество «открытых» (то есть отредактированных и несохраненных) записей в портале. Отметим, что только портал позволяет открыть несколько записей одновременно, это позволяет сымитировать обработку записей в режиме транзакции.
Вызвать событие Commit можно программно: командой Commit Record. Но вообще оно происходит при выходе из режима редактирования: когда пользователь кликает мышью на форме за границами редактируемых полей, или когда пользователь переходит на другую запись или на другой макет или когда выходит из режима просмотра. Важно: изменения, произведенные в глобальном поле, не приводят к «открытию» записи и не вызывают событие Commit при выходе из редактирования.
При разработке однопользовательских локальных приложений помните, что команда Commit Record не гарантирует сохранения произведенных изменений в файле базы данных. При срабатывании команды Commit Record изменения сохранятся в образе базы данных, с которым идет работа. Дело в том, что в локальном приложении пользователь работает с базой данных не напрямую, а через кеш. Это кусок базы данных, хранящийся в оперативной памяти. Все изменения вносятся сначала в образ, потому что попытка записывать каждое изменение на жесткий диск очень замедлила бы работу пользователя. При накоплении данных в кеше, либо строго через определенные интервалы времени кеш сохраняется на жесткий диск, происходит обновление файла. Если вдруг приложение резко прекратит работу в момент, когда данные находятся в кеше (выключение компьютера, принудительная остановка процесса, сбой приложения), последние действия пользователя так и останутся не зафиксированными в базе данных. Поэтому для предотвращения потери данных следует в локальном приложении после выполнения ответственных процедур принудительно сбрасывать кеш на диск и обновлять файл БД. Делается это командой Flush cash to disk.
В завершение остается добавить, что по умолчанию новые файлы базы данных создаются с настройкой «сохранять изменения автоматически», при выходе из режима редактирования изменения вносятся в базу данных сразу, без запроса подтверждения.
Можно снять эту опцию, и тогда событие Commit будет сопровождаться диалогом:
Событие Commit Record можно перехватывать триггером OnRecordCommit в настройках макета. При выходе из режима редактирования будет запущен скрипт, определенный триггером. Запись в базу не будет произведена, если скрипт завершить по команде Exit Script [Script Result: 0]. Запись останется «открытой». Чтобы, напротив, записать изменения в базу, в этом сценарии следует использовать команду Exit Script [Script Result: 1].