Предпочтительный способ написания приложений базы данных Delphi с транзакциями и компонентами данных

StackOverflow https://stackoverflow.com/questions/3833432

Вопрос

Что является предпочтительным способом записи приложений базы данных Delphi с использованием транзакций, а также компоненты для удовлетворения данных?

Я должен написать клиентское приложение, в котором доступа к таблицам InnoDB и выполняет некоторые вещами в мастер-подробностях внутри транзакций. После проведения некоторых исследований по транзакциям (от общей точки зрения), то я смиренно делаю вывод о том, что компоненты не в курсе данных и вручную SQL будет «идеальным совпадением» транзакций; Но компоненты программы данных не будут. Кажется, они не делаются друг для друга.

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

Может кто-нибудь, пожалуйста, просветите меня? Я поглотил это, но я не нашел никакого полезного ответа. Возможно, потому что мой английский недостаточно хорош, чтобы мои ключевые слова ограничены.

Кстати, я использую Delphi 7 и в настоящее время оцениваю Unidac в качестве библиотеки доступа к данным.

Спасибо.

РЕДАКТИРОВАТЬ

Пример, чтобы описать аспект моего вопроса:

Представьте себе форму с 2 дггридами на нем. Первая сетка Mastergrid и над ним эти кнопки: Добавить, редактировать и удалять. Вторая сетка подробно. Если пользователь нажимает Добавить, то он идет так:

  • Connection.starttransaction.
  • Master.append, затем master.post, затем master.edit (так что основной набор данных имеет первичный ключ AUTOINCREMELS, и теперь он редактируется)
  • Покажите форму редактирования модули, в котором пользователь заполняет основные записи, а также добавлять некоторые детали записи, используя другую форму.
  • Если пользователь Нажмите OK, приложение сделает Master.post и Connection.comMit. Если пользователь нажмите «Отмена», то приложение будет делать подключение. Rollback.

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

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

Редактировать 2

Я благодарю всех вас за участие в своем добре. Я выбираю ответ от VCDLEVEловы, потому что это самое близкое решение для моей текущей потребности.

Это было полезно?

Решение

Другие упомянуты с использованием комбинации DataSetProvider и ClientDataSet, чтобы иметь пакетное обновление, но в случае использования компонентов ADO или Unidac вам не нужен дополнительный слой DataSetProvider + Client DataSet, потому что ADO и Unidac поддерживают обновления пакетных данных.

Для Адо., что вы должны сделать, это установить Locktype. вашего набора данных ltbatchoptimistic. Отказ Для UniDac., вы должны установить Кашеupdate. имущество Истинный.

Это изменение делает ваш набор данных кэшируйте все изменения, которые вы делаете в записи в памяти, и отправьте их в целом в базу данных только при звонке Updatebatch. Метод (ADO) или KetsoUsdates. Метод (Unidac).

Теперь, что вы должны сделать, это позволить вашему пользователю вставить / редактировать запись в основной набор данных и независимо от того, какие записи он / она хочет в наборе данных сведений, используя любые компоненты, которые вам нравятся. Все изменения будут кэшированы. Когда ваш пользователь сделан, вы можете начать новую транзакцию и сначала сначала вызовите Utishbatch (или knsicaupdate в случае Unidac) для основного набора данных, а затем для деталей набора данных, и если все идет нормально, совершить транзакцию.

Это сделает ваши транзакции короткими без необходимости дополнительного слоя ClientDataset.

С уважением

Другие советы

Я понимаю ваш вопрос, я думаю. При открытии тадодатасата, например, 10 рядов данных, которые необходимо отредактировать в форме, с компонентами по программам данных, есть ситуации, в которых вы хотели бы кэшировать все изменения, выполненные для всех 10 строк (и, возможно, делеции и вставки) и совершить его как одну партию. Вы не можете открыть транзакцию в первом изменении, для этого блокируют другие пользователи, изменяющие те же данные. Транзакции должны быть максимально короткими.

Что я делаю в набросенном сценарии, используется следующие компоненты в цепочке:

Tadoconnection >> Tadodataset >> TDataSetProvider >> TCLINGDATASET >> TDATASORCE >> TDBEDITS и т. Д.

Теперь все изменения кэшируются в TCLINTDATATASET, и вы можете называть его методом ksantupdates для публикации всех изменений в одной быстрой транзакции. Ум на то, что также возможно использовать несколько тадодатателей и несколько TClientDataSets для структуры MASTER-DELIT (-DETAIL-ETC) с вложенными наборами наборах. Все изменения мастер-деталей также могут быть кэшированы и применяться в одной партии в одной транзакции. Смотрите помощь и ресурсы в других местах для всех деталей о реализации этого. Сначала это не легко. Но если вы поняли это, это легко и предлагает тонны возможностей. (Оффлайн редактирование, изучение изменений до их применения и т. Д.)

Чтобы избежать необходимости выполнять большие транзакции, которые я использую DataSetProviders а также ClientDataSets (даже локально).

Рассмотрите возможность использования этого как своего рода кеша, и он дает вам лучшее из обоих миров. Вы можете использовать контрольные элементы управления данными, чтобы упростить вещи при работе на UI. Действия пользователей по набору данных «записаны» клиентамидателями (вроде кеша базы данных).

Когда ваш пользователь готов к спасти изменения в базе данных (например, данные счета все находятся), вы называете KetsoUsdates. Способ для набора данных (ы).

В простейшем сценарии, где все наборы наборов данных находятся в разделе «Мастер-подробные отношения» (вложенные поставщиком), провайдер запускается и совершает / откатывает транзакцию сама по себе, поэтому вы полностью или ничего не являетесь.

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

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

Мои 2 цента.

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

Общее решение, как уже дано, состоит в том, чтобы использовать промежуточный уровень (клиентскийadataset). Но реальная проблема с вашим сценарием заключается в том, что вы не можете получить значение автоинкремента для главного стола без Master.append и Master.post, и, следовательно, вы начинаете записывать транзакция задолго до того, как она на самом деле требуется.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top