4 Ocak 2012 Çarşamba
Oracle bağlantısındaki yavaşlık
Thread.Sleep kullanımı
IIS 7.5/7.0 üzerinde ASP.Net 2.0 integrated modda çalıştırılıyorsa maxConcurrentRequestsPerCPU değeri default 12.
XmlSerializer'ın yavaşlığının resmidir
Selamlar,
Internette xml serializer kullanımının yavaş olduğu konusunda birçok makale görebilirsiniz.
Bu durumu, canlı sistemin resmini çekerek göstermek istedim.
Aşağıdaki ekran görüntüsünde serileştirme 5.527 ms sürmüş,
Bu sürenin 1788 ms’si serileştirme işlemini yapacak dinamik assembly’nin oluşturulup derlenmesi ve belleğe yüklenmesinde,
1.300 ms’si schema’yı oluşturmada,
1.951 ms’si difgramı yazmada geçmiş.
Gerçek serileştirme işi ise sadece 162 ms sürmüş.
Üstelik kaybımız sadece zaman da değil, gereksiz işlemlerde geçen süre boyunca çok değerli olan cpu ve ram kaynakları da harcanıyor.
İki sistemin de kendi sistemimiz olduğunu düşünürsek veri alışverişinde gidip gelen data’nın formatını bildiğimiz için örnekte 1.300 ms süren schema oluşturma işlemi tamamen gereksiz hale gelmektedir.
Verinin önceki ve şimdiki halinin birlikte gönderilmesi gerekmiyorsa, sistemler arasında veri alışverişinde zaman ve kaynak kullanımını azaltabilmek için DataTable’i xml olarak serileştirmeden önce mutlaka .AcceptChanges() metodunu çağırmalıyız. Böylece Diffgram oluşturmada geçen örnekteki 1951 ms’yi engellemiş oluruz.
Tarık
"An existing connection was forcibly closed by the remote host" hatası
Selam arkadaşlar,
Wcf servislerini kullanırken "An existing connection was forcibly closed by the remote host" hatası geliyorsa servis katmanında ele alınmayan bir hata var demektir.
Gerçek hatanın sebebini görebilmek için çözüm olarak iki alternatif mevcut:
[ServiceBehavior(
IncludeExceptionDetailInFaults = true
)]
Ya da
<serviceBehaviors>
<behavior name="EmployeeManager_Behavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
DataBinder.Eval kullanımı performansı düşürmekte
Selamar,
Uygulamalarımızda reflection kullanımının gecikmelere neden olduğunu biliyoruz, fakat ne boyutta olduğunu görmeyince insan fazla önemsemiyor.
Dynatrace’deki 30 dakikalık gözlemde şu sonuç ortaya çıkınca aslınca çok ama çok önemsenmesi gerektiği anlaşılıyor.
Bu rakamlar müşteri test ortamında elde edildiği için canlı ile bire bir aynı olmayabilir fakat reflection’dan kaynaklanan gecikme çok net görülüyor.
Bugün avicode’da hataları ve performans durumunu incelerken bir kayıt dikkatimi çekti:
BookingNavlunListele metodu içinde veritabanı sorguları dahil bir çok kod işletilmesine rağmen 216 + 134 = 350 ms zaman alırken verilerin gride bağlanması 952 + 1052 = 2004 ms zaman almış. Toplam 3.2 sn’nin 2 sn’si binding’de geçmiş. Sebebini anlamak için biraz araştırmanın ardından basit bir test uygulaması geliştirdim. Bind işleminde geçen süreleri ms cinsinden aşağıda görebilirsiniz:
Bind("Id") | DataBinder.Eval(Container.DataItem,"Id") | ((System.Data.DataRowView)Container.DataItem)["Id"] | |
1 istek | 702 | 649 | 693 |
699 | 699 | 709 | |
706 | 649 | 678 | |
3 istek | 10320 | 10036 | 572 |
5751 | 4900 | 575 | |
5358 | 4924 | 664 | |
5 istek | 6002 | 6313 | 669 |
5210 | 5613 | 701 | |
5244 | 4970 | 546 | |
10 istek | 4824 | 5145 | 544 |
4330 | 3827 | 582 | |
6507 | 6176 | 574 |
(Makinenin o anki durumundan ve anlık şartlardan bağımsız olarak karşılaştırma yapmayı garanti edebilmek için her durum 3 kez örneklenmiştir)
Server’e tek istek gelmesi durumunda Databinder.Eval kullanımının bir zararı yok gibi görünse de aynı anda çok fazla istek gelmeye başlayınca durum değişiyor.
http://msdn.microsoft.com/en-us/library/2d76z3ck.aspx adresinde Microsoft bu durumu uyarı şeklinde belirtilmiş:
“Because this method performs late-bound evaluation, using reflection at run time, it can cause performance to noticeably slow compared to standard ASP.NET data-binding syntax. Use this method judiciously, particularly when string formatting is not required.”
Özetlemek gerekirse DataBinder.Eval kullanımını azaltabilirsek sayfalarımızın performansı artacaktır.
Tarık
19 Aralık 2011 Pazartesi
Reporting Services Previous Function
Previous Function (Reporting Services)
Detay satırında, bir önceki satırdaki değeri okumak için kullanılıyor.
Örnek
Bir önceki değerle karşılaştırıp, bulunulan satırdaki görsel öğeler ile oynananabilir. (Bir önceki satırla aynı değere sakip olan bir alanı “Bold” yapmak gibi)
Expression for FontWeight
=iif(Fields!NUMARA.Value=Previous(Fields!NUMARA.Value),"Bold","Normal")
Buradan ayrıntılı bilgi alınabilir.
http://msdn.microsoft.com/en-us/library/ms156372%28v=sql.100%29.aspx
15 Aralık 2011 Perşembe
Bir işlemin (transaction'in) otomatik olarak çalıştırılması.
Bir işlemin (transaction'in) otomatik olarak çalıştırılması.
TXN’i zamanlanmış göreve ekletirken göz önünde bulundurulması gereken bir konu ; Request Message’daki alanlara hangi değerler atandıysa o değerler kullanılır. Örneğin, request mesaja her seferinde farklı bir lokasyon id geçilemez.
Hangi periyotta çalıştırılması isteniyorsa, devreye alım ekibine bildirilir.
Örnek-1
<Transaction Name=" KpkKontTarihceHizmetTutarGuncelle" Group="HS" Module="Genel " UserId="0">
<Schedule Frequency="Daily" StartHour="21" StartMinute="15" StartSecond="00"/>
</Transaction>
Örnek-2
<Transaction Name=" UretilemeyenDosyaLogTekrarGonder" Group="Loglama" Module="EntOzel" UserId="0">
<Schedule Frequency="Hourly" HourInterval="2"/>
</Transaction>
UserId’inin etkilediği bir durum yoktur. Zamanlanmış görevi çalıştıran kullanıcı 850’dir. Normal olan otomatik çalışacak TXN’in sıfırdan yazılmasıdır. Eğer hazırladığınız işlem sadece bu iş için yazılmadı ise, hem arayüzden hem otomatik olarak çalıştırılacak ise, TXN içine aşağıdaki gibi bir kontrol eklenerek tek TXN üzerinden işlemler yapılabilir. Burada dikkat edilmesi gereken husus, herhangi bir entegrasyonun bu TXN i çağırır ise onun da kullanıcı id’si 850 olduğu için aynı kod bloğuna girecek olmasıdır.
public void Execute(KpkKontTarihceHizmetTutarGuncelleRequest request, KpkKontTarihceHizmetTutarGuncelleResponse response)
{
bool scheduledJobMode = (request.KullaniciId == EntegrasyonConstants.EntUserId);
if (scheduledJobMode)
{
Artık burada ne isteniyor ise...
2 Aralık 2011 Cuma
LLBLGEN FETCH YAPMADAN GUNCELLEME VE SILME / SAVE AND DELETE WITHOUT FETCHING THE OBJECT
Objeleri üzerinde “update” ve “delete” işlemlerini , objeyi “id’si ile new’lemeden” dolayısıyla, Veri tabanına bir “select” atmaya gerek duymadan yapmanın bir yolu var.
Silme işleminde hiç bir sıkıntı yok. Hatta tüm silmeleri böyle yapmamız gerekiyor diyebilirim. Fakat güncelleme’de “re-factor” yaparken dikkat edilecek bir husus var. Eğer new’lenen objede, güncellediğiniz alanlar dışında başka bir alandan bilgi alıyorsanız o alan boş gelecektir, ama güncellenecek alan belli, değer belli ise, yapıştırın gitsin. Aşağıda örneği var.
Kolay gelsin.
Bildiğimiz, sevdiğimiz kullandığımız yöntem L
KpkKontTarihceHizmetEntity guncellenecekKpkKontTarihceHizmetEntity = new KpkKontTarihceHizmetEntity(55); //burda VT’te select attı. Objeji doldurdu.
transactionHelper.AddElementToTransaction(guncellenecekKpkKontTarihceHizmetEntity);
guncellenecekKpkKontTarihceHizmetEntity.tutar = 500;
guncellenecekKpkKontTarihceHizmetEntity.Save();
Güncelleyeceğimiz objenin ID’sini biliyorsak kullanacağımız, cillop gibi yöntem J
KpkKontTarihceHizmetEntity guncellenecekKpkKontTarihceHizmetEntity = new KpkKontTarihceHizmetEntity();
guncellenecekKpkKontTarihceHizmetEntity.Fields["Id"].ForcedCurrentValueWrite(55); //(llblgen’de generate işleminde readonly=false ayarlanırsa, id’te direkt atama yapılabilir)
guncellenecekKpkKontTarihceHizmetEntity.IsNew = false;
transactionHelper.AddElementToTransaction(guncellenecekKpkKontTarihceHizmetEntity);
guncellenecekKpkKontTarihceHizmetEntity.tutar = 500;
guncellenecekKpkKontTarihceHizmetEntity.Save();
Ayrıntılı Açıklama
Modifying an entity
Modifying an entity's data is just as simple and can be done in multiple ways:
- Loading an existing entity in memory, alter one or more fields (not sequenced fields) and call Save()
- Create a new entity, set the primary key values, set the IsNew to false, set one or more other fields' values and call Save(). This will not alter the PK fields.
- Via one of the UpdateMulti*() methods defined in the collection class of the entity.
Option 1 is likely the most used one, since an entity might already be in memory. As with all the suggested options, the Save() method will see that the entity isn't new, and will therefore use an UPDATE query to alter the entity's data in the persistent storage. An UPDATE query will only update the changed fields in an entity that is saved, which results in efficient queries. If no fields are changed, no update is performed. A field which is set to the same value (according to Equals()) is not marked as 'changed' (i.e. the field's IsChanged flag is not set).
If you've loaded an entity from the database into memory and you've changed one or more of its primary key fields, these fields will be updated in the database as well (except sequenced/identity columns). Changing PK fields is not recommended and changed PK fields are not propagated to related entities fetched in memory. You also can't save changed PK fields in recursive saves.
An example for code using the first method:
// [C#]
CustomerEntity customer = new CustomerEntity("CHOPS");
customer.Phone = "(605)555-4321";
customer.Save();
This will first load the Customer entity "CHOPS" into memory, alter one field, Phone, and then save that single field back into the persistent storage. Because the loading of "CHOPS" already set the primary key, we can just alter a field and call Save(). The Update query will solely set the table field related to the entity field "Phone".
Reading an entity into memory first can be somewhat inefficient, since all we need to do is an update of an entity row in the database.
Option 2 is more efficient in that it just starts an update, without first reading the data from the database. The following code performs the same update as the previous example code illustrating option 1. Even though the PK field is changed, it is not updated, because it is not previously fetched from the database.
// [C#]
CustomerEntity customer = new CustomerEntity();
customer.CustomerID="CHOPS";
customer.IsNew=false;
customer.Phone = "(605)555-4321";
customer.Save();
We have to set the primary key field, so the Update method will only update a single entity, the "CHOPS" entity. Next, we have to mark the new, empty entity object as not being new, so Save() will call the Update method, instead of the Insert method. This is done by setting the flag IsNew to false. Next is the altering of a field, in this case "Phone", and the call of Save(). This will not load the entity back in memory, but because Save() is called, it will be marked out of sync, and the next time you'll access a property of this entity's object, it will be refetched from the persistent storage. Doing updates this way can be very efficient and you can use very complex update constructs when you apply an Expression to the field(s) to update. See for more information about Expression objects for fields Field expressions and aggregates.
|
28 Ekim 2011 Cuma
EDI Entegrasyon Projelerinin BizTalk Server 2006’dan BizTalk Server 2010’a Taşınması
EDI Entegrasyonları Taşınmasında Temel Yapılacaklar;
1. BizTalk Server 2006'daki mevcut entegrasyon BizTalk Server 2010'a taşınır.
2. Entegrasyondaki EDI schema, bu schemanın yeni formatı ile değiştirilir. (yeni EDI file 'C:\Program Files (x86)\Microsoft BizTalk Server 2010\XSD_Schema\EDI\MicrosoftEdiXSDTemplates\EDIFACT' klasöründen seçilerek entegrasyona eklenir. )
3. Entegrasyondaki EDI schema değiştirildikten sonra mapteki bağlantılar kopar. Bu bağlantılar yeni schema ile map üzerinde tekrar yapılır.
4. Map yeniden düzenlendikten sonra orchestrationa 'StartLog' eklenir (Entegrasyonun yeni sistemdeki -Bizwatch- loglamaya uygun çalışması.).
5. Örnek input dosya ile test yapılır.
6. Entegrasyon build / deploy edilir.
7. Bu entegrasyonun .dll'i, BizTalk Administrations'ta ilgili applicationın altnda Resources kısmına eklenir.
8. BizTalk Administrations'ta entegrasyonun receive location, receive port ve send portları oluşturulur ve entegrasyonun orchestrationı ile ilişkilendirilir.
9. Entegrasyon için Party tanımlaması yapılır.
10. Entegrasyonun .dll'i, loglamanın çalışabilmesi için Bizwatch'a yüklenir.
11. Entegrasyonun orchestrationı başlatılıp örnek input dosyası ile çalıştırılır.
Karşılaşılan Teknik Sorunlar;
1. 2006 Projesinde 'Property schema' kullanıldıysa bu schema 2010'da kaldırılmalı. Kaldırılmazsa proje Bizwatcha yüklenirken hata veriyor.
2. EDI çıktı almada sorun çıkabiliyor. Bu durumda; EDI schemada UNH2 segmentinin fieldlarının değerleri map üzerinden değil, schemada (UNH2.1, UNH2.2...)-> properties->Default Value ya yazılarak verilmesi gerekiyor.
-> UNH2.1 = COPARN -> UNH2.2 = D -> UNH2.3 = 95B -> UNH2.4 = UN -> UNH2.5 = ITG14
3. RFF fieldı mandatory olmadığı için; kullanılmadığı zamanlarda properties->minOccurs = 0 yapılmalı, yapılmadığında TDT fieldından önce RFF fieldı değerini boş gördüğü için hata veriyor.
=> Conditional olan fieldların minOccurs özelliği 0 yapılmalı.
4. COPARN çıktısının UNB segmentinde fazladan fieldlar var;
UNB+UNOA:1+BTS-SENDER:ZZZ+RECEIVE-PARTNER:ZZZ+110715:1616+116' olması gereken satır
UNB+UNOA:1+BTS-SENDER:ZZZ+RECEIVE-PARTNER:ZZZ+110715:1616+116++++0++0' şeklinde geliyor. Kırmızı olan alanlar 2006'da yok. Biztalk 2010'da gelmiş bir özellik. Bu alanlar kaldırılamadı. Müşteri tarafından bu hali ile denendi, sorun olmadığı için bu hali ile bırakıldı.
5. COPARN çıktısının TMP fieldı kullanılmadıgında sorun yok, hem xml hem de edi olarak çıktı alınabiliyor. Bu field kullanıldığı zaman Biztalk Administration hataya düşüyor -dehydrated-, XML çıktıları alınıyor ama edi çıktıları alınamıyor:
Çözümü:
Visual Studioda input (XML) schemada; root-> EQDLoop1-> TMP-> C239-> C23901 fieldının Properties'inden 'Base Data Type' = xs:string seçilecek.
PARTY ve AGREEMENT OLUŞTURMA:
a. İki adet party oluştur(entegrasyonun çalışacağı iki uç, ör: Yılport – ARKAS):
Figure1:Party properties
Party'ye isim verdikten sonra, bu partynin çalışacağı entegrasyonun EDI send portlarını bu party'ye ekle:
Figure 2: Party send ports tanımlama
b. Bu iki party altında birer adet Business Profile oluştur:
Figure 3: Party altında Business Profile oluşturma
Oluşturulan Business Profile'in identities tabı aşağıdaki gibi tamamlanır:
Figure 4: Business Profile Identities
c. Bu iki party için yeni bir Agreement oluştur:
Figure 5: Agreement oluşturma – genel özellikleri
(Parties-> YILPORTBooking->YılportBookingAgreement)
- Kırmızı ile belirtilen tablardan ilki receiver->sender, ikincisi sender-> receiver şeklinde olacak.
- Bu sayfada 'code qualifier (UNB2.2 ve UNB3.2)' = <NotValued> olarak seçilecek.
- Her iki tabdada 'Character sets and seperators' = UNOA
- İlk tabda 'Transaction Set List' de UNH 2.1 = COPARN olacak ve 'Support Transaction Sets from List' seçili olacak
- Her iki tabda da 'Validation' da, UNH2.1 = COPARN yazılacak (alttaki resimde olduğu gibi).
- İkinci tabda(sender-> receiver) BizTalkta tanımlanmış olan send portlar gösterilecek (edi çıktısı alınacak send portlar).
14 Ekim 2011 Cuma
Sharepointte “Exception of type 'System.OutOfMemoryException' was thrown.” şeklinde bir hata aldığınızda, sharepointin çalıştığı application pool’ un worker process sayısını arttırarak çözüm sağlayabilirsiniz.
Sharepointin çalıştığı sunucuda IIS Manager’ ı açıp, application pool’ un özelliklerinden, Performance sekmesinde gerekli ayarı yapabiliriz.
Microsoft KB: http://support.microsoft.com/kb/823547/en-us
Configuring Web Gardens with IIS 6.0 : http://technet.microsoft.com/en-us/library/cc784869(WS.10).aspx
6 Ekim 2011 Perşembe
ORACLE 11G LISTAGG Birden fazla satırı gruplayıp tek satır haline getirmek
Bir sorguda alt alta gelen satırları belirli bir grup bazında birleştirerek gösterme işlemini tek fonksiyon ile yapabiliyoruz.
Bunu sağlayan fonksiyon “LISTAGG”
MUSADR.MUSTERI_ID-> Gruplanan, tek satır gelecek bilgi
ADRES_METINIà bu fonksiyon ile birleştirilen, tekrar eden satırlar
',' à Ayırac
SELECT MUSADR.MUSTERI_ID, LISTAGG(ADRES_METINI,',' ) WITHIN GROUP (ORDER BY ADRES_METINI) AS ADRES
FROM MUSTERI_ADRESI MUSADR
group by MUSADR.MUSTERI_ID
3 Ekim 2011 Pazartesi
Reporting Services Belli Sayıda Detay Kayıdı Göstererek Gruplama (yeni sayfaya geçme)
Detay TabliX’inin Group ifadesine aşağıdaki değer girilir. Gruptan sonra “Page Break” yap seçeneği işlenirse, istenilen sayıda kayıt yazdıktan sonra sayfa atlatılmış olur.
=Floor((RowNumber(Nothing) - 1) / 10)
KAYNAK
Add a group to your report and use the following expression to group on: =Floor((RowNumber(Nothing) - 1) / 10) Also set the 'Page break at and' property for the group. Peter
http://www.sqlservercentral.com/Forums/Topic490774-147-1.aspx
30 Eylül 2011 Cuma
Rapor Projesi Derlenmiyorsa, ClassLibrary Hatası Veriyor İse
YNAREPORT2008 de , derlenmeyen proje varsa, rapor önizleme yapmıyorsa , ClassLibrary Hatası Veriyor İse
Rapor Projesini Açıyoruz..
YNAClassLibrary Projesini Derliyoruz. Oluşan DLL’leri
C:\Projects\YENI NESIL ACENTELIK (YNA)\Genel\YnaReport2008\YNAClassLibrary\bin\Debug
Klasöründen kopyalayıp
C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies
Klasörüne yapıştırıyoruz.
Count(*) Count(1) Count(Kolon_adi)
SELECT
COUNT (*) CountYildiz_NulldaOlsaSayar,
COUNT (1) Count1_Nulldahil1KabulEdpSayr,
COUNT (D.TRANSIT_TASIMA_TIPI_ID) CountAlanAdi_NullariSaymaz,
COUNT (DISTINCT D.TRANSIT_TASIMA_TIPI_ID) CntDistinct_NulldnFrkliKacAdt
FROM dok_konsimento d
The parameter to the COUNT function is an expression that is to be evaluated for each row. The COUNT function returns the number of rows for which the expression evaluates to a non-null value. ( * is a special expression that is not evaluated, it simply returns the number of rows.)
There are two additional modifiers for the expression: ALL and DISTINCT. These determine whether duplicates are discarded. Since ALL is the default, your example is the same as count(ALL 1), which means that duplicates are retained.
Since the expression "1" evaluates to non-null for every row, and since you are not removing duplicates, COUNT(1) should always return the same number as COUNT(*).