Delphi Can

Orjinalini görmek için tıklayınız: Database listelemede pas geçme
Şu anda (Arşiv) modunu görüntülemektesiniz. Orjinal Sürümü Görüntüle internal link
Merhaba; Garip bir durumla karşı karşıya kaldım.

VCL'de Timer ile belirli aralıklarla databaseyi kontrol ediyorum sorunsuz olarak kayıt varsa sonuca cevap alıyorum.
Multi-Device Application ile aynı kodları çalıştırdığımda kayıt olmasına rağmen zaman, zaman pas geçiyor yani Timer databasedeki kayıta 3, 4. seferde kontrolde cevap veriyor. Bu sorun neden kaynaklanıyor olabilir? 
Benzer durum başka kodlarda da oluyor mesela butona tek tıklamada db'den veriler listelenmiyor, ikinci kez butona tıklama yapmak durumunda kalıyorum.


begin
  with Hatirlat, Form3.ListViewPopup do
    try
      TimerDBKontrol.Enabled := False;
      ControlDateTime := Now;
      Connection := FDConnecMain;
      Close;
      SQL.Clear;
      SQL.Add('Select * From HATIRLAT Where TARIH <=:Tarih And Saat <=:Saat And DURUM=''Okunmadı''');
      Params[0].AsDate := DateOf(ControlDateTime);
      Params[1].AsTime := TimeOf(ControlDateTime);
      Prepared := true;
      Open;
      if Not IsEmpty then
      begin
        TimerPopupFormShow.Enabled := true;
      end;
    finally;
      Hatirlat.Close;
      TimerDBKontrol.Interval := 30000;
      TimerDBKontrol.Enabled := true;
    end;
end;
Merhaba
sorunun kaynağı için bişi söylemek erken
ama görebildiğim şöyle bir sorun var.
where kısmındaki tarih ve saat birleştirip zaman <= :zaman olarak parametre yapmanda fayda var
gün olarak koşulu sağlasa bile saat olarak sağlamayabilir
veritabanında tarih 06.03.2018 saat 09:00 olsun
03.03.2018 08:00
03.03.2018 10:00
parametrelerinden biri where koşulunu taşımayacağından eksik listeler
Timer içinde yazdığınız kodlar main thread dışında, farklı bir thread'de çalışır. Bu yüzden Timer içinde DB bağlantısında dikkatli olmalısınız. Timer içine özel (OnTimer içinde Create-Free edilen) DB bağlantı bileşenleri kullanmanızı tavsiye ederim.
Merhaba.

- Elektronik cihazlarda bir sorun olunca önce kablosu prize takılı mı diye sorarız. Şimdiki söyleyeceğimi garipsemeyin diye böyle girizgah yaptım.  Smile

- Anladığım kadarıyla Desktop ile kayıt / değişiklik gerçekleşiyor. Tablet veya Mobil başka bir cihaz ile SQL ile durum irdeleniyor.

- Üçüncü başka bir Win32 bilgisayar yardımı ile kaydedilen verinin commit edilip edilmediğini ( yani veritabanına yazılıp yazılmadığını ) benzer sql sorgusu ile kontrol ederek testlere başlayabilir misiniz ? 

- En azından bu ihtimali devre dışı bırakırsanız rahatlıkla bir sonra aşama olarak mobil cihazın servera erişim şekli içerisinde TRY FINALLY yerine TRY EXCEPT ile hata sorgulamalarına bakılabilir.
EXCEP ile hata yakalamayı denedim, fakat hata hiç vermedi.
Timeri Interval := 30000 saniye olarak ayarlıyorum normalde 30 saniye dolunca var olan dbdeki veriyi göstermesi lazımken, bu durum 2 veya 3. dakikada buluyor. Sanki kodlar koşullar tutmamış gibi algılıyor.
Mesajım eksik anlaşılmış.

Öncelikle veritabanına gerçekten kayıt düşüyor olduğunun teyidini almak lazım. 

Bunu mobil değil, kaydı düşen makine de değil, üçüncü başka bir bağımsız Win32 (Dekstop/Notebook Windows) makine ile ( veya aynı bilgisayarda bağımsız başka bir proje ile de olur ) deneyimlemek lazım.

Kayıt düşüyor ise sonucun elde edildiği aynı süreyi Mobil cihaz ile takip etmek, ancak o zaman mobile geçmek arıza takibi için doğru olur demek istemiştim.

Bir de SORGUNUZUN altına bir SORGU daha ekleyin. Var olan bir kaydı görüntüleyen cinsten olsun. Bu veritabanı bağlantısının sağlam olduğunu teyid edecektir. Yani 30 saniyede bir sorgu yapılıyor, sonuç alınıyor ama tablo boş dönüyor olma ihtimaline karşılık, mesela tablodaki ilk kaydı çeken  bir sorgu, veritabanı erişiminin sağlıklı olduğu konusunda fikir verecektir.
(07-03-2018, Saat: 09:17)SimaWB Adlı Kullanıcıdan Alıntı: [ -> ]Timer içinde yazdığınız kodlar main thread dışında, farklı bir thread'de çalışır. Bu yüzden Timer içinde DB bağlantısında dikkatli olmalısınız. Timer içine özel (OnTimer içinde Create-Free edilen) DB bağlantı bileşenleri kullanmanızı tavsiye ederim.

Maalesef bu bilgi doğru değil. Timer içinde yazılan kodlar ana thread içinde çalışır. Uygulamanın mesaj kuyruğuna gelen WM_TIMER mesajlarının işlenmesine dayanan bir mantığı vardır. Bu durumu test etmek için aşağıdaki gibi küçük bir test yapılabilir:

procedure TForm1.FormCreate(Sender: TObject);
begin
 Memo1.Lines.Add( 'Main Thread ID:' + TThread.CurrentThread.ThreadID.ToString() );

 TThread.CreateAnonymousThread(
   procedure
   begin
     Memo1.Lines.Add( 'Anon Thread ID:' + TThread.CurrentThread.ThreadID.ToString() );
   end
 ).Start;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
 Memo1.Lines.Add( 'Timer Thread ID:' + TThread.CurrentThread.ThreadID.ToString() );
end;
Evet çok haklısınız Tuğrul Bey. Uyarı için teşekkürler. Şimdi yazdığımı okuyunca ben de şaşırdım. İş yoğunluğu arasında, foruma balıklama dalınca oluyor bazen böyle şeyler Big Grin
Açıklama için herkese teşekkürler.