Форум: "Начинающим";
Текущий архив: 2005.10.30;
Скачать: [xml.tar.bz2];
ВнизADO+Acess Найти похожие ветки
← →
Серг73 (2005-10-05 10:11) [0]2-а клиента:
TADOConnection>TADOTable>>Acess2002
после очень недолгой (1-2 мин) параллельной работы первый клиент выдает "Не могу найти строку для обновления" (на операции "ADOTable1.Delete"). Вопросы с таким текстом сообщения просмотрел, кое-что попробовал... все то-же самое...
Эти 2 клиента написаны специально для иллюстрации ошибки возникающей в реальном проекте... ошибку никак не отловлю (собственно со связкой ADO-Access первый раз работаю)...
Помогите плз...
делают следующее:
первый беспорядочно удаляет записи
по таймеру 0.1 раз в секунду:
procedure TForm1.Timer1Timer(Sender: TObject);
var
SearchOptions: TLocateOptions;
IntFlDelete: integer;
begin
Timer1.Enabled:=False;
SearchOptions:=([loCaseInsensitive]);
TableRefresh(ADOTable1);
ADOTable1.First;
while not ADOTable1.Eof do
begin
IntFlDelete:=Random(3);
if IntFlDelete>1 then
begin
ADOTable1.Delete;
TableRefresh(ADOTable1);
end;
ADOTable1.Next;
end;
Timer1.Enabled:=True;
end;
procedure TableRefresh(Tbl: TADOTable);
var
RecN: integer;
begin
RecN:=Tbl.RecNo;
Tbl.Close;
Tbl.Open;
if RecN>Tbl.RecordCount then RecN:=Tbl.RecordCount;
if RecN>0 then Tbl.RecNo:=RecN else Tbl.First;
end;
второй добавляет:
по таймеру 0.1 раз в секунду:
procedure TForm1.Timer1Timer(Sender: TObject);
var
SearchOptions: TLocateOptions;
tmpstr,source,text: string;
i,IntFlDelete: integer;
begin
Timer1.Enabled:=False;
SearchOptions:=([loCaseInsensitive]);
TableRefresh(ADOTable1);
for i:=1 to 10 do
begin
source:=IntToStr(random(10000));
text:=IntToStr(random(10000));
if ADOTable1.Locate("source;text;",VarArrayOf([source,text]), SearchOptions)
=False Then
begin
ADOTable1.Append;
ADOTable1.FieldByName("source").Value:=source_name;
ADOTable1.FieldByName("text").Value:=text;
ADOTable1.Post;
end;
end;
Timer1.Enabled:=True;
end;
procedure TableRefresh(Tbl: TADOTable);
// такая-же процедура
Provider=Microsoft.Jet.OLEDB.4.0
в базе есть ключ-счетчик (случайные длинные)
← →
sniknik © (2005-10-05 11:27) [1]> собственно со связкой ADO-Access первый раз работаю
видно. до этого видать строго на локальных базах (dBase/...) сидел.
переделай, удаления/вставки сделай через sql команды. ADOTable выкини и забудь про него (советую вообще с панели убрать, его и ADQQuery)
на RecNo тоже никогда не завязывайся, вместо него используй ключевое поле.
p.s. тут не ошибку искать надо тут надо полностью теределывать.
← →
msguns © (2005-10-05 12:54) [2]Обрати особое внимание на параметры коннекта: CursorLocation, IsolationLevel и др.
← →
zx © (2005-10-05 14:25) [3]Access - экзотическая система, с одной стороны это локальная СУБД, а с другой с ней лучше работать как с SQL сервером.
← →
Серг73 (2005-10-06 09:01) [4]> Обрати особое внимание на параметры коннекта: CursorLocation,
> IsolationLevel и др.
clUseServer/ilCursorStability и clUseClient/ilCursorStability
- 1-е приложение выдает, что "Не могу найти строку для обновления".
CursorType: доступны только ctKeyset и ctStatic, как на clUseServer, так и на
clUseClient.
некоторые другие IsolationLevel"ы позволяют добится сообщения о блокировке от 2-го приложения... :(
Собственно непонятно как может возникнуть непонятка с ADOTable1.Delete,
записи нигде не меняются, добавляет их другое (2-е) приложение и автоподстановки с автоинкрементным ключевым полем у 1-го непоняток вызвать не должно... вроде....
← →
Серг73 (2005-10-06 09:12) [5]> переделай, удаления/вставки сделай через sql команды. ADOTable выкини
> и забудь про него (советую вообще с панели убрать, его и ADQQuery)
ADOQuery1-же для sql запроса и нужен-же... а как (через какой компонент) вы посоветуете выполнять sql запросы?
> на RecNo тоже никогда не завязывайся, вместо него используй ключевое
> поле.
Как при Tbl.Close;Tbl.Open; по ключевому полю активность записи восстановить? А чем RecNo плох?
попробую, спасибо...
← →
msguns © (2005-10-06 09:51) [6]>Серг73 (06.10.05 09:01) [4]
Прежде чем тупо перебирать варианты параметров, очевидно, следовало бы почитать, ЧТО они обозначают. Внимательно.
>Серг73 (06.10.05 09:12) [5]
>А чем RecNo плох?
Жмем F1 на TADQuery и просто читаем:
The value of RecNo for a given row in a recordset is relative to the rows that precede the current row. Thus, if a check of RecNo for a row indicates 10 and then a preceding row is deleted, a subsequent inspection of RecNo will show a new position of 9.
Или говоря по-нашему, по-бразильски, нельзя привязывать конкретную запись НД к RecNo т.к. при переоткрытии НД номер этой записи элементарно может измениться. Другими словами, RecNo не идентифицирует запись (в отличие, например, от PK/UID), а лишь определяет ее позицию относительно начала текущего датасета как множества записей непосредственно на клиенте, а никак не на сервере, которому в высшей степени наплевать, какие там рекно у клиентов.
Банкомат выдал тебе запрошенную сумму денег, а что ты с нею будешь делать и в каком порядке планируешь использовать купюры, ему глубоко фиолетово.
Единственное, имхо, полезное применение этого св-ва - отображение состояния НД при визуализации его в контролах типа гридов. Сообщение "Запись 135-я из 1000" в статусной строке формы может быть весьма полезна пользователю при просмотре достаточно большого объема информации.
← →
sniknik © (2005-10-06 10:59) [7]> а как (через какой компонент) вы посоветуете выполнять sql запросы?
все что возвращает результат (рекордсет) в TADODataSet, все что не возвращает в TADOCommand (можно еще в ADOConnection.Execute но тут есть специфика (поначалу лучше не надо))
> Как при Tbl.Close;Tbl.Open; по ключевому полю активность записи восстановить?
locate (для access еще возможен seek по индексу) по ключу.
а еще лучше переделать логику чтобы не переоткрывать (слишком часто хотябы), рекордсеты. ну вот скажи так ли уж нужна эта новая только добавленная запись? пользователь вместа анализа существующего должен на постоянно мигающий монитор пялится?
> А чем RecNo плох?
тем, что его вообще может не быть (значение -1 для всех записей), а еще тем что даже если он есть и стоит к примеру на 3й записи, а удаляют 2ю то последующая установка будет на 4ю запись (если считать от начального рекордсета). нелогично.
← →
Silver... © (2005-10-06 11:03) [8]
DataSet.Refresh
илиDataSet.Close/Open
Надо делать.
Один клиент редактировал данную запись второго потом ломает без Refresh
← →
Серг73 (2005-10-06 11:56) [9]ADOTable использую и в "procedure TableRefresh" этот ADOTable Close/Open...
вот через sql попробовал в обоих приложениях работать... тот-же результат... sql запрос теперь ту-же ошибку выдает...
← →
Silver... © (2005-10-06 12:28) [10]Может
Client 2 питается изменить запись которую в этот самый момент редактирует Client 1
← →
Silver... © (2005-10-06 12:41) [11]
> ADOTable использую и в "procedure TableRefresh" этот ADOTable
> Close/Open...
Так правельно ты ж отредактировал запись, питаешся запомнить а оказывается ее до тебя уже поредактировали ты в ауте. Надо
1.Cancel сделать а уж потом Refresh или Close/Open
2.Быстро быстро редактируем а потом Post
3.Надеемся никто не редактировал до нас :)
А вобше Вроде настроыки есть (не помню точно) чтоб всегда записывалась последняа отредактированная на www.delphikingdom.ru посмотри статью про ADO
← →
Серг73 (2005-10-06 13:29) [12]> Так правельно ты ж отредактировал запись, питаешся запомнить
> а оказывается ее до тебя уже поредактировали ты в ауте. Надо ...
1-й клиент только удаляет записи, без разбора, по rnd. 2-й клиент только добавляет через append... я правильно понимаю, что пока post не вызван - запись на пересылается? edit"ов нет нигде... правда есть автоинкрементное поле, но для только_удаляющего (а именно у него проблема) клиента это наверное всеравно...
через ADOCommand1 на sql append/delete перевел...
тоже самое...
на серверные курсоры перехожу - блокировка возникает...
← →
msguns © (2005-10-06 13:39) [13]Тебе же сказали: вместо редактирования датасета используй одиночные запросы в рамках того же коннекта.
Везде выставь серверный курсор и соотв. уровень изоляции. Тогда оба клиента "увидят" изменения конкурента.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2005.10.30;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.063 c