multi Thread içinden veritabanı bağlantısı sorunu

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
huradem
Üye
Mesajlar: 5
Kayıt: 26 Ağu 2003 04:29
Konum: İstanbul

multi Thread içinden veritabanı bağlantısı sorunu

Mesaj gönderen huradem »

Merhabalar,
içinden bir türlü çıkamadığım bir sorunum var.

Seri porttan gelen bilgileri okuyup, ilgili bilgiyi veritabanında birtakım işlemlerle

sorgulayıp yine seri porttan göndermesi gereken bir program yazmaya çalışıyorum.

Veritabanı olarak firebird kullanıyorum.

Veritabanı sorgulanırken birçok tablodan veri sorgulaması ve gelen değerlere göre yeni

birtakım işlemler yapılması gerektiği için bir SP yazdım ve işlemi veritabanına

yaptırıyorum. SP parametre olarak seri porttan gelen değeri alıyor ve göndermem gereken

değeri döndürüyor.

Seri porttan gelen değerler, ne zaman ne sıklıkla geleceği belli olmayan şeyler olduğu için;

bu işlem için de bir thread oluşturdum.

Eğer bilgisayarda tek bir port varsa, 1 thread oluşturuluyor ve hızlı bir şekilde sorunsuz

çalışıyor. Ama eğer ikinci bir seri port kullanılmak istenirse, yeni bir thread

oluşturuluyor. Eğer 2 thread var ise bir süre çalışıp ikisi birden ölüyor.

Tespitime göre sorun veritabanından kaynaklanıyor.

Veritabanı işlemleri kaldırınca sorun yok.

SP içinde bolca sorgu ve kontrolün ardından bir dosyaya sonuç giriliyor. Ama aynı dosya

sorgulmanın da bir parçası.

Bağlantı için Zeos, IB, Dbexpress hepsini denedim ama sonuç değişmedi.

Dbexpress daha hızlı çalışıyor ama o da çöküyor.

Program çalışmaya devam ediyor aslında ama thread mefta oluyor.

Program system try kısmına yerleşerek çalışıyor.

Ana formda 4 adet (en fazla 4 port olacağı düşünülerek) theread değişkenim var. Her thread

kendi değişkeni üzerinden oluşturuluyor.


örn: Thread2:=PortDinle.Create(mHandle);



thread içinde ise

constructor PortDinle.create(const FormHandle:HWND);
Begin
inherited create(true);

fAnaFrmHandle:=FormHandle;

FreeOnTerminate:=True;

Resume;
End;



FormHandle, ana formla iletişim için kullanılıyor,


Database bağlantı nesnelerini ana form üzerine koydum,
her thread için kendi içinde execute bölümünde oluşturdum ama sonuç değişmedi.

Birşekilde kayıt kitlenmesi mi oluşuyor,
DeadLock mı luşuyo anlamadım.



Kısaca 2 thread aynı veritabanı üserinden select ve insert yapmaya çalışınca gümlüyor.
Ve bu işlemleri SP kullanarak yapıyorlar.

Her thread için ayrı SP çalıştırınca da sorun çözülmedi.

Yardımmm.....
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

Thread çalışmaları yaparken aynı sorun ile karşılaşmıştım. Problem VT'ye bağlanırken yolu 'C:\DB\VT.FDB' olarak vermemdi. Network path verince sorun çözülmüştü. Firebird local file'larde multithread yapamaz. 'localhost:C:\DB\VT.FDB' olarak kullanman gerekir.
Hakan Can
Üye
Mesajlar: 634
Kayıt: 04 Mar 2005 04:27
Konum: Ankara

Mesaj gönderen Hakan Can »

Veritabanına bağlanırken her bir thread için TSession veya TSQLConnection'una kadar bütün DB componentlerini Thread içinde ayrı ayrı create etmelisin. Yani her bir Thread'in kendine ait ve de mümkünse kendi içinde create edilmiş TQuery, TDatabase ve TSession'u (BDE) veya TSimpleDataSet ve TSQLConnecton'u (dbExpress) olması gerekir.

İyi çalışmalar.
huradem
Üye
Mesajlar: 5
Kayıt: 26 Ağu 2003 04:29
Konum: İstanbul

Mesaj gönderen huradem »

Thread içerisinde, bağlantı için gerekli her nesneyi kendi içerisinde oluşturdum. Veri tabanı sorgulrını seri porttan veri geldikçe çelıştırıyorum. Bir thread çalışıyorsa sorun yok. Birden fazla thread yoğun bir şekilde çalışıyorsa sorun çıkıyordu.



fduman
"Thread çalışmaları yaparken aynı sorun ile karşılaşmıştım. Problem VT'ye bağlanırken yolu 'C:\DB\VT.FDB' olarak vermemdi. Network path verince sorun çözülmüştü. Firebird local file'larde multithread yapamaz. 'localhost:C:\DB\VT.FDB' olarak kullanman gerekir."


bu yöntem ilginçtir başta işe yaradı gibi gözüktü. Uzun süre kitlenme olmadı ama sonunda yine kitlendi.


Her thread için ayrı ayrı bağlanınca, aynı kayıtlara, aynı anda erişmeye çalışma durumu oluşuyordu ve sanırım bu durumda DeadLock denen hadise meydana geliyordu.

Sonuç olarak veritabanı bağlantısını thread içerisinden çıkarttım.
Ana forma koydum. Thread ana formun kendisi için ayrılmış header'ına mesaj gönderip istekte bulunuyor, gelen isteğe göre veritabanı sorgulamasını ana formdaki nesneler hallediyor. Böylece aynı anda her port dinlenebilmekle birlikde sadece 1 veritabanı bağlantısı oluşmuş oldu.

Hız biraz düştü ama, en azından sorunsuz çalışıyor.

Hız hala kabuledilebilir düzeyde olduğu için şu anda sorun çözülmüş gibi.

Teşekkür..
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

huradem yazdı: bu yöntem ilginçtir başta işe yaradı gibi gözüktü. Uzun süre kitlenme olmadı ama sonunda yine kitlendi.
Hala kilitleniyor ise thread yapını yanlış kurmuşsun. Kodu görmeden birşey söylemek pek mümkün değil.
Kullanıcı avatarı
Nick_
Üye
Mesajlar: 122
Kayıt: 01 Eki 2007 09:28
Konum: Konya

Mesaj gönderen Nick_ »

fduman yazdı:
huradem yazdı: bu yöntem ilginçtir başta işe yaradı gibi gözüktü. Uzun süre kitlenme olmadı ama sonunda yine kitlendi.
Hala kilitleniyor ise thread yapını yanlış kurmuşsun. Kodu görmeden birşey söylemek pek mümkün değil.

thread yapını yanlış kurmuşsun. Kodu görmeden birşey söylemek pek mümkün değil :lol:
Kullanıcı avatarı
Battosai
Üye
Mesajlar: 1316
Kayıt: 01 Eki 2007 12:02
Konum: Ankara

Mesaj gönderen Battosai »

MultiThread olayı karışıktır biraz.Thread'e bulaşan herkes muzdarip bu tarz vakalardan.Firebird kullanmadığım için pek bilmem ama her durumda MultiThread desteklemesi lazım ki senin threadler bi işe yarasın öteki türlü yolla sırayla gitsin(Gerçi Niye sırasıyla yollayıp almıyorsun değerleri illa thread lazım değilki...)
Kullanıcı avatarı
sadettinpolat
Moderator
Mesajlar: 2131
Kayıt: 07 Ara 2003 02:51
Konum: Ankara
İletişim:

Mesaj gönderen sadettinpolat »

bircok thread ile birlikte ayni baglanti uzerinden firebird veritabanina ekleme , silme, guncelleme tarzi islemler yaptirdim. belirli bir sure duzgun giderken arasira transaction hatasi ya da veritabani okunamadi tarzi hatalari aldim. hata mesajlarini internette arastirdigimda sorunun winsock ile ilgili oldugu bilgisine ulastim. cozumu her thread icinde veritabanina ayri bir baglanti kurarak asmistim.
"Sevmek, ne zaman vazgececegini bilmektir." dedi, bana.

---
http://sadettinpolat.blogspot.com/
Cevapla