Aynı anda farklı tablolara kayıt etme ile ilgili sorun.

Firebird ve Interbase veritabanları ve SQL komutlarıyla ilgli sorularınızı sorabilirsiniz. Delphi tarafındaki sorularınızı lütfen Programlama forumunda sorunuz.
Cevapla
boreas
Üye
Mesajlar: 120
Kayıt: 05 Tem 2007 12:39
Konum: Ankara

Aynı anda farklı tablolara kayıt etme ile ilgili sorun.

Mesaj gönderen boreas »

Merhaba arkadaşlar,
yazdığım programda eğer kullanıcı bir fatura kesiyorsa fatura kesim işleminden sonra bunu müşterinin cari hesabına kaydediyor ve irsaliyeli fatura ise stokdan düşüyor. Sistemi 2012'den bu yana kullanıyoruz. Çok sorunlada karşılaşmıyoruz ama bazen müşterinin hesabına kayıt etmediğini ya da stokdan düşmediğini görüyorum. Yazılımla ilgili olsa sorun sürekli olur diye düşünyorum. Ama tektük karşılaşıncada ne yi atladığıma anlam veremedim. Fikirlerinizi paylaşırsanız sevinirim.
....
Kullanıcı avatarı
yhackup
Üye
Mesajlar: 115
Kayıt: 09 Ağu 2014 09:09
İletişim:

Re: Aynı anda farklı tablolara kayıt etme ile ilgili sorun.

Mesaj gönderen yhackup »

Programdan mı kayddiyorsun, yoksa trigger mi kullanıyorsun *
Çaylak Delphici :D

Yakup ULUTAŞ
boreas
Üye
Mesajlar: 120
Kayıt: 05 Tem 2007 12:39
Konum: Ankara

Re: Aynı anda farklı tablolara kayıt etme ile ilgili sorun.

Mesaj gönderen boreas »

Programdan triggerla cozemiyorum
....
Kullanıcı avatarı
yhackup
Üye
Mesajlar: 115
Kayıt: 09 Ağu 2014 09:09
İletişim:

Re: Aynı anda farklı tablolara kayıt etme ile ilgili sorun.

Mesaj gönderen yhackup »

transaction commit rollback kullanabilirsin, sql scriptini gönderdiğinde, o session'da hata olursa işlemlerin tümünü geri alır.
Çaylak Delphici :D

Yakup ULUTAŞ
boreas
Üye
Mesajlar: 120
Kayıt: 05 Tem 2007 12:39
Konum: Ankara

Re: Aynı anda farklı tablolara kayıt etme ile ilgili sorun.

Mesaj gönderen boreas »

Hatayi algilasam tekrar kaydi göndereceğim ama hata gözükmüyor ya da kullanıcılar oyle diyor
....
mkysoft
Kıdemli Üye
Mesajlar: 3103
Kayıt: 26 Ağu 2003 12:35
Konum: Berlin
İletişim:

Re: Aynı anda farklı tablolara kayıt etme ile ilgili sorun.

Mesaj gönderen mkysoft »

İlgili işlemleri bir transaction ile mi yapıyorsunuz yoksa connection ile mi?
boreas
Üye
Mesajlar: 120
Kayıt: 05 Tem 2007 12:39
Konum: Ankara

Re: Aynı anda farklı tablolara kayıt etme ile ilgili sorun.

Mesaj gönderen boreas »

Connection kullaniyorum. Zeos bilesen paketi
....
mkysoft
Kıdemli Üye
Mesajlar: 3103
Kayıt: 26 Ağu 2003 12:35
Konum: Berlin
İletişim:

Re: Aynı anda farklı tablolara kayıt etme ile ilgili sorun.

Mesaj gönderen mkysoft »

@boreas farklı işlemleri aynı connection içinde yaptığınız bu şekilde sorun olması çok normal. Şimdiye kadar karşılaşmamımız süpriz olmuş. Büyük ihtimalle lokal ağ sağlıklı çalıştığı içindir. Bu tür işlemleri transaction özelliği ile yapmalısınız. İşlemlere başlamadan önce connection nesnesinin StartTransaction olayını çağırın, işlemler başarılıysa Commit olayını çağırın son olarak.
boreas
Üye
Mesajlar: 120
Kayıt: 05 Tem 2007 12:39
Konum: Ankara

Re: Aynı anda farklı tablolara kayıt etme ile ilgili sorun.

Mesaj gönderen boreas »

@mkysoft orda bir anlatım yanlışlığım olmasın. Zeoslib transaction bileşeni kullanmıyor direk connection kullanıyor connection bileşeninde de autocommit açık yazdığım bilgi direk onaylanıyor. Bildiğim kadarıyla ADO IBX gibi bileşenlerde transaction parçası var ben onu kastettim .

@ramazan_t hatırlatman için teşekkür ederim. Gördüğüm hata sıklıkla firebird INET/inet_error: read errno = 10054 hatası. Ama daha yakından takip edeceğim.
....
Kullanıcı avatarı
greenegitim
Üye
Mesajlar: 713
Kayıt: 28 Nis 2011 10:33
Konum: İstanbul

Re: Aynı anda farklı tablolara kayıt etme ile ilgili sorun.

Mesaj gönderen greenegitim »

bu sorun bir iki defa bana da söylendi bende her incelediğimde bir hata bulamadım ve programa cariye işlenmemiş faturalar cariye işlenmemiş kasa kayıtları şeklinde kontroller koydum ama hiç bir zaman öyle bir sorun görünmüyordu toplamlar da aldırdım yine bir sıkıntı göremedim kullanıcılar o faturayı tekrar değştir kaydet yaptığını söyledi düzelmiş yaklaşık 10 bin faturada 2 defa olmuş bu. firebird loglarını açtığımda bende de sıklıkla firebird INET/inet_error: read errno = 10054 hatası gördüm bu ağda kopmalardan elektrik kesintilerinden kaynaklı olduğunu düşünüyorum. Sadece 2 defa şununla karşılaştım hareketi çok olan bir fatura kayıt edildikten hemen sonra o faturadaki stokkodunun kalan miktarı güncellenmemişti 4-5 sn sonra tekrar baktığımda güncellendi ana makineyi kontrol ettiğimde hdd yi yoğun kullanan bir kaç uygulama gördüm bundan kaynaklı olduğunu düşündüm.

Faturayı cariharekete kaydederken insert sql ilemi gönderiyorsunuz yoksa dataset.insert; dataset.post şeklindemi.
Mücadele güzelleştirir!
boreas
Üye
Mesajlar: 120
Kayıt: 05 Tem 2007 12:39
Konum: Ankara

Re: Aynı anda farklı tablolara kayıt etme ile ilgili sorun.

Mesaj gönderen boreas »

Insert/ post olarak gönderiyorum ama sql kayıtların daha kararlı çalışdığı kanısındayım. Yalnız bende forced write kapalı durumdaymış onuda aktif hale getirdim. Local'de değil ama uzak bağlantıda sıkıntı var. Dediğin gibi kontrol mekanizması koyup hatalı buldukça arkada düzeltebilirim yalnız bunlarda hep ayak üstü çözüm gibi geliyor yarın butür çözümler için form açılışları vs. lerde yavaşlamaya başlayacak diye çokda canım çekmiyor.
....
Kullanıcı avatarı
greenegitim
Üye
Mesajlar: 713
Kayıt: 28 Nis 2011 10:33
Konum: İstanbul

Re: Aynı anda farklı tablolara kayıt etme ile ilgili sorun.

Mesaj gönderen greenegitim »

benimki paranoyaklıkan biraz oyle bir şey koymam işlenmeyen faturaları bulabilirsem sorunu da bulabilirim diye koymuştum ama hiç çıkmadı şimdiye kadar. cariharekete kayıt atarken mutlaka insert sql ile atın dataset.insert; dataset.posta yaşamıştım bu tip sorunlar daha sonra hep uzun görünsede insert sql kullanmıştım daha hızlı ve daha güvenli. yanlış hatırlamıyorsam @tugrulhelvaci hocamızın önerisiydi insert edit işlemleri için sp yapıp bu işlemleri sp yıkmak burada bahsi geçiyor http://webcache.googleusercontent.com/s ... clnk&gl=tr site kapalı olduğu için google cache inden çektim linki.
bunu buraya da yazmakta fayda var sayfanın uçup gidebilme ihtimaline karşı.
Mücadele güzelleştirir!
Kullanıcı avatarı
greenegitim
Üye
Mesajlar: 713
Kayıt: 28 Nis 2011 10:33
Konum: İstanbul

Re: Aynı anda farklı tablolara kayıt etme ile ilgili sorun.

Mesaj gönderen greenegitim »

Merhabalar, size dilim döndüğünce ve bilgim yettiğince yardımcı olmaya çalışayım.

Öncelikle "Neden katmanlı mimari kullanmak istiyoruz, client-server programlama bizim işimizi neden görmüyor ?" sorusunu kendimize sormamız ve cevabı üzerinde bir müddet düşünmemiz gerekiyor sanıyorum. Katmanlı mimari hepimizin geçmek istediği ama kuralları ve yapılması gerekenleri gördüğümüzde uzak durduğumuz ve işin kolayına yani client-server mimariye yöneldiğimiz ilginç bir metodoloji aslında.

Hepimizin bildiği gibi client-server mimaride; herhangi bir dilde yazılmış olan client uygulama herhangi türde bir veritabanına bağlanır ve gereken işlemleri yapar. Bu durumda da kullanılabilen bir kaç farklı senaryo vardır. Kimi yazılımcılar, business rules adı ile anılan iş kurallarını veritabanı üzerinde kodlamak istemezler, tüm iş kuralları client uygulama üzerinde durur. Bunun elbette bazı nedenleri vardır. Birinci neden üşengeçlik ve kolaycılıktır. İkinci neden ise yazılacak olan uygulamanın birden fazla veritabanına destek verilmesinin işveren tarafından diretilmesidir.

Ancak, okuyucularımın affına sığınarak söylüyorum ki, bu son derece yanlış bir düşünce tarzıdır. Aslında burada yanlış olan birden fazla veritabanına destek vermek değildir, yanlış olan destek verilecek veritabanlarının kendine has güçlü yanlarından feragat etmek ve her veritabanı sağlayıcısının sunduğu Ansi-SQL ile client tarafında işlem yapmaktır.

"Peki bunun ne gibi sıkıntıları vardır, neden Ansi-SQL kullanmayalım ki, yazılımcıların çoğu yanlış mı yapıyor ?" Maalesef bu sorunun kısa ve net cevabı, "Evet" tir.

En basit anlamda, client uygulama içinde veritabanına yönelik işlemler Ansi-SQL ile yapılır ise; bu durumda veritabanına giden sorgular optimize edilmemiş biçimde giderler ve veritabanınız ilişkisel bir veritabanı ise bu sorguları optimize etmek için uğraşır ki bu da bir zaman kaybıdır. Çözüm ise stored procedure'lerdir. Stored procedure'ler veritabanı üzerinde depolanmış SQL cümleleridir. Veritabanı üzerinde depolandıkları için veritabanının kendisine ait SQL dilinde kodlanabilirler dolayısı ile veritabanının kendisine has güçlü yanlarını kullanma imkanı sunarlar. Aynı zamanda Stored Procedure'ler ilk çalıştırıldıklarında veritabanı sunucusu tarafından optimize edilirler ve daha sonraki çağrımlarında mevcut optimizasyon üzerinden çalıştırılırlar. Bu da daha hızlı çalışmalarını sağlar.

Aynı zamanda, client uygulamanız içinde Ansi-SQL'leri kullanmanız network trafiğini de olumsuz yönde etkileyecektir. Kısa bir örnek vermeme müsaade edin lütfen;

select adi, soyadi, yasi, maasi from Persons

kodu mu daha az byte'a sahiptir yoksa;

sp_GetPersons

kodu mu ? Elbetteki stored procedure notasyonunda network ortamında giden verilerinizde ciddi bir kazanım elde etmiş olursunuz. Network'ün rahat olması, darboğazların olmaması uygulamanızın hızını az da olsa etkileyebilecek unsurlardan bir tanesidir.

Gelelim iş kurallarına.. Maalesef pek çok yazılımcı iş kuralları'nı client uygulamalarının içinde yazmaktadır. Bu da kuralların bir şekilde değişmesi durumunda client uygulamaların upload edilmesi sonucunu doğurur. Aynı zamanda, hedef veritabanınız üzerinde bir başka programın yada bir veritabanı uzmanının yada bir bilgi işlem elemanının yapacağı yanlış hareketlere engel olamazsınız anlamına gelir.

Örneğin;

Bir cari hareket tablonuz olsun. Bu tablo üzerinde herhangi bir cariye ait birden fazla kayıt olsun. Diyelim ki bu cari hareketlerden bir yada birden fazlasının silinmesi neticesinde bir başka tablo üzerindeki bazı kayıtların da silinmesi gerekiyor. Tüm iş kurallarını client uygulama üzerinde yazan birisinin bu işlemleri uygulaması gerekir. Ancak, ya birisi SQL Query Analyser gibi bir program ile yada kendi yazdığı bir uygulama ile sizin veritabanınıza bağlanıp, Cari hareket tablonuz üzerinden bir kaç kaydı siler ise ???

Bu durumda, sizin uygulamanız içinde yazmış olduğunuz kuralların hiç bir anlamı kalmayacaktır. Normalde cari hareket kayıtları ile birlikte silinmesi gereken kayıtlar maalesef veritabanınızda kalmaya devam edecek ve veritabanının tutarlılığı zarar görecektir. Peki ne yapmalıyız diye soruyorsanız eğer o kısmı detaylıca ilerleyen satırlarda izah edeceğim. Biz nelerin yanlış olabileceği hususları etrafında biraz daha dolaşalım ki; yanlışları bilenin doğrularının daha fazla olabilmesini sağlayalım.

O halde, peki ya client-server mimaride bizler; business rule(iş kuralları)'larımızı veritabanı üzerinde kodlarsak ve insert/update/delete/select gibi bilgi üzerinde işlem yapan komutlarımızı da stored procedure olarak kodlarsak client-server'ın nesi yanlış olabilir sorusunu sorabiliriz.

Evet bu client-server mimarinin en optimum ve en güzel kullanım tarzlarından birisidir. Ancak hatalı olmamak ile birlikte bazı hususlara yeterince cevap veremez. Örneğin; Win32 ortamında bir client uygulamanız olduğunu düşünelim. Kullanıcılar ile etkileşim kurarken iş kurallarını hem client üzerinde hem de veritabanı üzerinde kodlamanız gerekir. Sadece veritabanı tarafında yapılacak kontroller belki yeterli olabilir ama gereksiz yere veritabanına külfet getirmenin de bir anlamı olmaz. Misal, veritabanı üzerinde bir tabloya bir e-mail adresi giriyorsunuz ve bu e-mail'in geçerli bir e-mail adresi olduğunu kontrol etmek istiyorsunuz. Eğer, bu kontrol kodunu sadece client tarafına koyarsanız ve veritabanı tarafına koymazsanız bu durumda sizin uygulamanızın dışından bir başka uygulama vasıtası ile tablonuza yanlış bir e-mail adresinin girişine müsaade etmiş olursunuz. Server tarafına koyup, client tarafına koymazsanız; basit bir e-mail validasyonu için veritabanının vaktini çalmış olursunuz. En güzel yol ise, her iki tarafta da bu kontrolün yapılmasıdır.

Bu şekilde bir uygulama yaptığınızda hemen hemen hiç sorununuz kalmayacaktır. Tâki, zamanın ve teknolojinin gereklerince uygulamanızın farklı platformlarda da çalışması zarureti yada isteği hasıl oluncaya dek. Örneğin, uygulamanızın web ortamında yada android işletim sistemli cihazlar üzerinde de çalışabilmesi istenir ise ne yapacağız ?

Bu durumda eski düşünce tarzı ile, hem web ortamında hem de android ortamlarında uygulama yazmamız icap edecek ve işin kötüsü tüm bu kuralları oralarda da uygulamamız gerekecek.

Gelelim "bence ne yapmalıyız" kısmına.

*1- Hangi veritabanı yada veritabanları ile çalışıyorsak, iş kurallarımızın hepsini trigger olarak kodlamalıyız. Bir tabloya kayıt girişi silme yada güncellemenin belirli koşulları vardır. Hemen hemen hepimiz client uygulamalarımızda bu koşulların gerçeklenip gerçeklenmediğini kontrol eder ve ona göre işlemimize devam ederiz. İşte bu kontrollerin hepsi before trigger yada SQL Server'ca instead of triggerlarında kontrol edilmelidir. Eğer kuralların dışında bir işlem yok ise, o halde insert/update yada delete işlemine izin verilmelidir. Eğer bir tablo üzerindeki insert/update yada delete işleminden bir başka tablo/tablolar bir şekilde etkilenecek ise bu durumda da after triggerlar kodlanmalıdır. Triggerların bu şekilde kodlanması; sistemin bütünlüğünün bozulmaması anlamına gelir. Aynı zamanda veritabanını yetkisiz işlemlerden yada hatalı işlemlerden de korur.

2- Veritabanı üzerinde birbiri ile ilişkili bütün tablolar foreign keyler ile birbirine bağlanmalıdır. Bu bağlantı sağlanır ise, trigger yazmayı unutmuş olsanız dahi, detayı olan bir master'ı silmenize müsaade edilmeyecek dolayısı ile yine tutarlılık korunacaktır.

3- Tablolarınız üzerinde sadece belirli verileri alabilen alanlarınız var ise, (örneğin cinsiyet sahası sadece erkek yada kadın olabilir, yahut kan grubu sahasının alabileceği değerler bellidir) bu gibi alanların içereceği değerleri veritabanı üzerinde bir check constraint ile belirtirseniz, isteseniz de cinsiyet alanı için erkek yada kadından başka bir değer giremeyecek ve veritabanı tutarlılığı için iyi bir adım daha atmış olacaksınız.

4- Veritabanı üzerinde her bir tablonuz için en az 4 adet stored procedure yazmalısınız. Bunlar Insert, Update, Delete ve Browse stored procedureları olmalıdır. Stored procedure'lerinizi bu şekilde yaptığınızda bu stored procedureler içinde kuralları kontrol etmemelisiniz. Bunlar sadece kendilerine düşen vazifeyi yani insert, update, delete işlemlerini uygulamalıdırlar(Hatırlayacağınız üzere kuralları triggerlarda kodlamıştık). Stored procedure yapısını kullanır iseniz, hem daha hızlı sorgu çalıştırmış olursunuz hem de network trafiğinde iyileşmeye neden olursunuz. Aynı zamanda, ufak tefek değişikliklere ihtiyacınız olduğunda, uygulamanıza kod ekleyip derleyip dağıtmak yerine stored procedure'nin içindeki kodu değiştirip yolunuza devam edebilirsiniz.

5-Her bir tablo için bir sınıf tasarlamalı ve bu tabloya yapılacak insert/update/delete işlemlerini bu sınıf ile sarmalamalısınız. Bu sayede, client uygulamanızda SQL cümleleri ile yada stored procedure'lerle boğuşmak yerine bir sınıfın metodunu çağırmanın güzelliğini yaşarsınız.*

Tüm bunları yaptıktan sonra katmanlı mimari anlam ifade etmeye başlayacaktır. Datasnap sayesinde, client'larınız içinde kodladığınız kurallar bütününü orta katmana alabilirsiniz. Böylece, sizden yeni bir web uygulaması yada android tabanlı bir uygulama istendiğinde kuralları yeniden yazmaya ihtiyaç duymazsınız. Client uygulamanızın hangi ortamda çalıştığı ile ilgilenmeden ve yüzlerce kuralı yeniden yazmakla zaman kaybetmeden sadece işinize odaklanırsınız.

Datasnap mimarisinin daha sayılabilecek onlarca güzel tarafı olabilir. Bunlar kısaca, iş kurallarına ev sahipliği yapmak ve her client uygulama için yeniden yazmayı engellemek; iletişim protokolünü veritabanından bağımsız hale getirmesi münasebeti ile her ortamdan erişilebilir olmak(web, android, blackbery, windows phone 7, iphone vs.); transport filtreleri ile giden ve gelen verileri sıkıştırabilmek, şifreleyebilmek dolayısı ile hız ve güvenlik kazanımı elde etmek, callback channell'ları ile orta katmanın client üzerindeki bir kodu çalıştırmasını sağlamak yada belirli bir kanala bağlı olan client'ların belirli bir şart gerçekleştiğinde haberdar olmalarını sağlamak sayılabilir.

Son söz olarak; tüm iş kurallarını veritabanı üzerinde uygulamanın bir zorunluluk olduğunu, orta katmanda hepsi olmasa da bu kuralların bir kısmının kontrol edilmesi gerektiğini, client uygulamada ise sadece basit giriş hatalarına müsaade edilmeyen kuralların kontrol edilmesi gerektiğini ifade edebilirim. Aynı zamanda eğer tablolarınızı orta katmanda bir sınıf şeklinde tasarlarsanız, orta katmana ulaşacak olan client uygulamaların sizin veritabanınızın desenini bilmesine ve kurallarını bilmesine ihtiyaç duymaksızın kodlama yapabilme imkanı kazanmış olursunuz. Tabii ki nesneye yönelik programlamanın vereceği hazzı saymıyorum bile.

Tüm bu yazılanların ışığında kafanıza takılan herhangi bir şey var ise yada anlatmakta yetersiz kaldığım bir husus var ise, yardımcı olmaktan memnuniyet duyarım.

yanıtlandı 20.04 '2012 saat 21:56
tugrulhelvaci's gravatar image

yazan : tugrulhelvaci
Mücadele güzelleştirir!
boreas
Üye
Mesajlar: 120
Kayıt: 05 Tem 2007 12:39
Konum: Ankara

Re: Aynı anda farklı tablolara kayıt etme ile ilgili sorun.

Mesaj gönderen boreas »

Çok güzel bir makale paylaşım için teşekkürler .
....
Cevapla