Мне нужна аналогия: триггеры и события - PullRequest
4 голосов
/ 30 января 2009

По другому вопросу, я сталкиваюсь с заблуждением, которое иногда возникает здесь, на SO. Некоторые спрашивающие считают, что триггеры относятся к базам данных, а события - к ООП.

У кого-нибудь есть хорошая аналогия, чтобы объяснить, почему это ошибочное сравнение, и последствия неправильного его применения?


EDIT:

Билл К. ударил его правильно, но, возможно, не видит важности критической разницы между событием и функцией обратного вызова, которая в любом случае поражает меня. Триггеры фактически вызывают выполнение кода каждый раз, когда происходит событие; обратные вызовы происходят только всякий раз, когда один зарегистрирован для события (что не верно для подавляющего большинства событий); и даже тогда, в большинстве случаев, первое действие обратного вызова - отменить регистрацию (или, по крайней мере, обратный вызов содержит квалификационный выход, поэтому он выполняется только один раз).

Если вы напишите триггер, он будет неизменно выполняться каждый раз, когда происходит событие, потому что нет способа зарегистрироваться или отменить регистрацию в сегменте кода.

Триггеры - это способ синхронно вставлять повторяющуюся логику в поток выполнения (т. Е. Синхронность). События - это средство отложить логику на более поздний срок (т.е. реализовать асинхронность).

Существуют исключения и смягчения в обоих случаях, но основные шаблоны триггеров и обратных вызовов в большинстве случаев противоположны по замыслу и реализации. Часто кажется, что различие не полностью утонуло (ИМХО, YMMV). : D

1 Ответ

8 голосов
/ 30 января 2009

Это не одно и то же, но они не связаны.

В обоих случаях механизм можно описать примерно следующим образом:

  • Какой-то блок кода декларирует «интерес» к изменениям в состоянии.
  • Ваше приложение влияет на некоторые изменения.
  • Система запускает блок кода в ответ на изменение.

Возможно, триггер базы данных больше похож на функцию обратного вызова, которая зарегистрировала интерес к определенному событию.

Вот аналогия: событие - это резиновый мяч, который вы бросаете. Спусковой крючок - это собака, которая гонится за брошенным мячом.

Если имеется в виду другое различие, которое делает его «опасным» (примечание: OP отредактировал этот выбор слов вне вопроса) для сравнения триггеров и событий, вы можете описать, что вы имеете в виду.


Триггеры - это способ вставить повторяя логику синхронно в нить исполнения (т.е. синхронность). События являются средством для отложить логику на потом (т.е. реализовать асинхронность).

Хорошо, я понимаю, что вы имеете в виду более четко. Но я думаю, что это в некоторой степени зависит от реализации. Я бы не предположил, что обработчик событий должен отменить свою регистрацию; это зависит от системы, которую вы используете. Например, обработчик сигналов UNIX должен предотвращать перехват нового сигнала, пока он уже обрабатывает его. Но сервлет Java внутри контейнера Tomcat должен быть потокобезопасным, поскольку он может вызываться одновременно несколькими потоками. Оба они являются обработчиками событий разных типов.

Обработчики событий могут быть синхронными или асинхронными. Может ли обработчик в системе публикации / подписки читать сообщения, которые были опубликованы недавно, но до того, как обработчик зарегистрирует свой интерес? Или только сообщения, отправленные одновременно?


Есть еще одна важная причина трактовать триггеры как отличные от обработчиков событий: я часто рекомендую против делать что-либо в триггере, которое влияет на состояние вне базы данных.

Например, отправка электронной почты, запись в файл, публикация в веб-сервисе или разветвление процесса недопустимы внутри триггера. Если по какой-либо другой причине, кроме транзакции, которая породила триггер, может быть выполнен откат, но вы не можете откатить эти внешние эффекты. Возможно, вы даже не используете явные транзакции, но, скажем, отправляете электронное письмо в триггере BEFORE, но операция завершается неудачей из-за ограничения NOT NULL или чего-то еще.

Вместо этого вся такая работа должна выполняться с помощью кода в приложении, после каждый подтверждает, что операция SQL была успешной и транзакция совершена.

Очень плохо, что люди продолжают пытаться выполнять неуместную работу внутри триггера. В MySQL есть старшие разработчики, которые продвигают UDF для чтения и записи данных в memcached. Вау - я только что заметил, что превратили его в продукт MySQL 6.0 !! Возмутительно!

Итак, вот еще одна попытка провести аналогию, сравнивая триггеры и события с процессом уголовного процесса:

  • ПЕРЕД триггером является утверждение.
  • Триггер AFTER является обвинительным актом.
  • COMMIT - осуждение после обвинительного приговора.
  • ROLLBACK - оправдательный приговор по невиновному приговору.

Вы хотите посадить преступника в тюрьму только после того, как он будет осужден.

  • Тогда как СОБЫТИЕ - это само преступление.
...