не задумываешь об этом, а тут значит следующая ситуация. Допустим я хочу сделать выборку данных из БД. Что мне нужно с транзакцией делать в таком случае? Commit? Но тогда закроется набор данных. CommitRetaining? Но тогда (если верить документации) будет активная транзакция с БД и её в любом случае надо будет закоммитить. Как же тогда в Делфи работает, не пойму. То есть там под капотом закрывается транзакция и вновь открывается набор данных? Но тогда бы и locate соскакивал...
Имхо, ты путаешь тёплое с мягким. Если у тебя датасет кеширует данные, то они в нём сохраняются, даже ПОСЛЕ коммита транзакции, если не кеширует, то ты должен брать оттуда данные ДО коммита транзакции. Все зависит от компонентов доступа, которые ты используешь. Дбгрид - лишь компонент визуального отображения данных.
Стикер
Тут не в этом дело. Чел вроде работает на MySQL, я о нем ничего не знаю. Но знаю, что точно также себя ведет связка Lazarus + FireBird + UniDac. Потому что вот: InterBase-like servers support several simultaneous active transactions within a single connection and require a transaction to be active when opening a cursor. ... Because InterBase and Firebird require an active transaction for any operation under data. Ты когда заходишь в какую нибудь тулзу для FireBird типа IBExpert-а или FireRobin-а, делаешь в них простенький SELECT, потом закрываешь приложение и оно тебе говорит, мол, как завершим транзакцию? Ты чешешь репу, какая к черту транзакция, я не делал ни INSERT, ни UPDATE, ни DELETE. А потому что такая специфика у FireBird, что он открывает транзакцию даже при SELECT-е. Так вот, когда активизируется DBGrid, начинается транзакция при его SELECT-е. Потом ты хочешь что-то INSERT-нуть в базу, пишешь StartTransaction(); и компонент доступа тебе выдает ошибку: мол нельзя открыть уже открытую транзакцию. Поэтому, как мы тут порешили, нужно заводить 2 транзакции, одну для DBGrid-ов, вторую для INSERT, UPDATE, DELETE.
Изначально автор сетовал на то, что "не успевает" отобразить данные в гриде, если явно управляет транзакцией(коммитит ее). Это характерно для некеширующих датасетов(например, IBSQL в IBX). В штатных компонентах Лазаря таких компонентов нет. Поэтому для него нет разницы, стоит у него автокоммит транзакции или ручное управление - НД будет содержать те данные, которые ему определили в SQL.Text Ты же говоришь про селективные и модифицирующие транзакции. Это из другой оперы
Т.е в Лазаре датасет выкачивает на клиента весь набор данных?
если набор двунаправленный то везде датасет выкачивается на клиента
Выкачивается, но не весь, а на размер буфера, в том же ibx ibquery это кажись всего 1000 записей. Поэтому странно было услышать что можно сразу же коммитить транзакцию в Лазаре
ibx выкачивает точно больше 1000 по дефолту. я предела не видел
Увы, да. Поэтому ими можно пользоваться только при отсутствии альтернатив. К счастью, есть uib, ibx, zeos
Мне бы не хотелось сделать то, что не понятно, чтобы оно как-то работало. Options может использоваться для управления поведением SQLDB для этой транзакции. stoUseImplicitИспользуйте неявную поддержку транзакций механизма базы данных. Это означает, что при вызове методов Commit или Rollback на сервер не будут отправляться явные команды запуска и остановки транзакции (что фактически делает их неоперабельными на уровне базы данных).stoExplicitStartЕсли они установлены, всякий раз, когда выполняется инструкция SQL, транзакция должна быть запущена явно. Поведение по умолчанию заключается в том, что TSQLStatement или TSQLQuery запускают транзакцию по мере необходимости. Есть понимание, что тут имеется ввиду? Полазил по форумам и не до конца тема раскрыта. На сколько я понял, имеется ввиду, что транзакция вообще не вызывается, а при командах INS del upd - она коммитится автоматически
Если я делаю commit, то данных как раз нет. В этом и проблема) Поэтому и используется CommitRetaining, специально для такого случая. Тогда и набор доступен, но и транзакция активная висит. Именно от этого эффекта я и хотел избавиться. И поэтому мы пришли к тому, что данные хорошо бы сразу получить и отправить куда-нибудь в Listview или stringgrid
Ты точно желаешь что-то не так. На крайний случай, сделай автокоммит привязанной транзакции. Возможно где-то может быть настройка типа "закрыть НД после коммита" - тогда надо снять ее
У меня вообще вся логика на ХП, поэтому транзакциями на клиенте управлять нет смысла.
на обычных гридах/наборах скорее всего никак. только либо грид менять либо инмемери наборы-прокладки добавлять
Возможно, да. До компа доберусь, посмотрю ещё раз настройки. Попробую выставить, как мне советовали ранее с stoUseImplicit
Например если используются mater-detail отношения. Или используются временные таблицы, с временем жизни до коммита транзакции.
I solved it function TForm6.RsaEncrypt(APlainText: string; APublicKey: TCertPem): RawByteString; var LRsa: TRsa; Pstr: PString; Encrypted: RawByteString; Bytes: TBytes; begin try LRsa := TRsa.Create; LRsa.LoadFromPublicKeyPem(APublicKey); Bytes := TEncoding.UTF8.GetBytes(APlainText); Pstr := Pointer(Bytes); Encrypted := LRsa.Pkcs1Encrypt(Pstr, length(Bytes)); Result := Encrypted; LRsa.Free; except on E: Exception do begin ShowMessage(E.Message) end; end; end;
да, это работает. спасибо
В общем оставил один компонент управления транзакциями, выставил у него stoUseImplicit, подключил коннекшн и query на него. Убрал из кода явное управление транзакциями. Пока полет нормальный) Предварительно - большое спасибо!)
явно управлять транзакциями иногда надо, но это случай редкий и скорее имеет отношение к написанию сервисов, которые наполняют БД (и там DBAware-компоненты в принципе не нужны) если клиент вынужден использовать явные транзакции для обработки данных из БД (или даже для внесения изменений) - то тут что-то не так в архитектуре БД
я предпочитаю всегда явно управлять транзакциями )
и на кой? чтобы данные в грид вывести? чтобы одну строчку изменить? или что там накручено?
я всей работой с БД управляю явно
Обсуждают сегодня