Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.042 c
2-1128722761
Serg!1!!
2005-10-08 02:06
2005.10.30
Grafika


8-1118165933
Charly22
2005-06-07 21:38
2005.10.30
Как быстро очистить Canvas?


1-1128932639
BanderLog
2005-10-10 12:23
2005.10.30
RadioButton + onChecking (onChecked)


14-1128934701
Anatoly Podgoretsky
2005-10-10 12:58
2005.10.30
Анти-антивирусы


3-1127142793
BaxTMaH
2005-09-19 19:13
2005.10.30
Странная ошибка





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский