Samstag, Dezember 25, 2010

X-Mas–The art of unit testing

Dieses Jahr habe ich mich mit “The art of unit testing” beschenkt. Wenn ich es gelesen habe, dann steige ich bestimmt zum Sennmeister für Unit testing auf. Winking smile

Dieses Jahr wurde in einem Projekt endlich Unit testing als sehr wichtiges Instrument genutzt. Allerdings haben wir das klassische Unit testing mit umfangreichen Intregrationstest verbunden. Allerdings mussten wir vorher in den Projekten lernen, was passiert, wenn die Tools nicht testbar sind und immer komplexer werden. Gerade bei der Architektur und dem Design muss auf eine gute Testbarkeit und Entkopplung wert gelegt werden. Derzeit ist für mich das Mittel der Wahl für IoC – Unity, obwohl mich ein Kollege immer von Spring überzeugen will. Bisher kann ich mich bei Spring nur für den AOP-Teil begeistern.

Wer unit tests für Grenzwerte oder mehrere Parameter schreibt, der sollte auch mal einen Blick auf Nunit Attributes schauen. Es gibt viele Möglichkeiten die Tests zu Parametrisieren und so ein bisschen auch FIT oder ähnliche Tools nachzuahmen.

Es gibt noch einiges zu tun in diesem Jahr, ich muss mich noch ganz schön ranhalten. Andererseits muss ich erst mal wieder richtig fit werden. Mein Körper holt sich in den letzten Wochen den fehlenden Urlaub. Obwohl ich mich nicht schlecht fühle, bin ich erst mal krankgeschrieben und muss mich entspannen.

Sonntag, Dezember 12, 2010

Query Performance–Open Source, Reflection und “Java”-Tools

Wie  üblich bei den meisten Applikationsentwicklungen ging es bei uns in den letzten Wochen u. a. um das Thema Performance. Die aktuelle Anwendung nutzt verschiedene Open Source Komponenten zum Verarbeiten der Daten. Die Komponenten sind convertierte Java-Entwicklungen, teilweise mit langem Hintergrund.

Zum einen muss ich sagen, dass man wirklich extrem Differenzieren muss zwischen den einzelnen Projekten. Teilweise sollte man vor dem Einsatz noch ein Code-Review und Analyse einschieben. Eine Open Source Komponente nutze Exceptions exzessiv zur Flusssteuerung, was schlechtes Design ist und u. U. Performance kostet. Leider nutzen wir auch eine Datenzugriffskomponente, die eigentlich fast keine Arbeit abnimmt, da damit nur Objektzuweisung durchgeführt werden. Ein OR-Mapper, der Arbeit abnimmt, würde eine wesentlich bessere und einfachere Entkopplung ermöglichen.

Die Datenzugriffskomponente, ich weigere mich OR-Mapper zu sagen, arbeitet intern heftig mit Reflection um die Properties zu setzen. Leider ist gerade bei Massenoperationen Reflection keine gute Wahl. Reflection ist ein zentraler Bestandteil im .NET Framework, dennoch kostet jede Operation dennoch einige Millisekunden, die wenigen Millisekunden potenzieren sich dann bei mehreren Tausend Objekten zu einigen Sekunden, im schlimmsten Fall zu Minuten. Allgemein sollte vor dem Einsatz eines OR-Mapper immer geprüft werden, ob es sich um Massenoperationen handelt, diese sollten ggf. mit klassischen ADO-Mitteln abgehandelt werden. Um unsere Roundtrips zur DB zu reduzieren, haben wir die verschiedenen Statements zu einem "großen" Statement zusammengefügt. Leider wurde dadurch das resultierende Objekt größer und die Property Zuweisungen haben sich auch vervielfacht. Aufgrund der Eltern-Kind-Beziehung in den Statements benötigten die Abfragen anschließend 40s (5s beim Ausführen in der DB). Grundsätzlich kann durch Joins die Abfragegeschwindigkeit gesteigert werden, OR-Mapper wie Lind2SQL oder NHibernate machen diese Optimierungen durchaus auch. Wir haben unsere Zugriffe durch Aufsplitten unserer Joins um das 10-fache beschleunigt. Die Joins wurden eingeführt, um einige DB-Roundtrips zu sparen, leider wurden unserer Datensätze dadurch aber auch ver-100-facht. 100-fache Datenmenge und viel Reflection haben sich so massiv ausgewirkt, dass wir bis zu 40s für einfache Selects benötigt haben. Somit wurden also 2 Statements abgesetzt, 1 die Elterndaten und die 2. Abfrage mit den Kinderdaten, in beiden Statements wurde die gleiche Bedingung benutzt. Wir haben die Zuordnung der Kinder zu Ihren Elternelementen im Code realisiert, da dies sehr einfach war und wir nicht ggf. 100te Roundtrips produzieren. Würde man zu jedem Customer (Beispiel) die entsprechenden Orders über den PK laden, wären dass ggf. sehr viele Operationen. Um das ganze weiter zu optimieren, kann man bei einigen Datenbankprovidern mehrere SQL-Operationen in einem Rutsch absenden, so dass die Weitere Zeit kaum ins Gewicht fällt.

Hier ein sehr abstraktes und einfaches Beispiel:

1 select * from Customers c 2 INNER JOIN Orders o ON c.ID=o.customerID 3 WHERE o.orderdate>@DATE; 4 /* Splittet into 2 Statements */ 5 select c.* from Customers c 6 INNER JOIN Orders o ON c.ID=o.customerID 7 WHERE o.orderdate>@DATE; 8 select o.* from Customers c 9 INNER JOIN Orders o ON c.ID=o.customerID 10 WHERE o.orderdate>@DATE;

Dies soll kein Post gegen Open Source oder konvertierte Java-Componente sein. Jedoch finde ich es falsch, einfach anzunehmen, dass gut funktionierende Java-Componenten, auch gut in .NET funktionieren. Es sollte immer der Anwendungsfall im Vordergrund stehen. Componenten/Frameworks sind nur Unterstützer zu diesem Weg. Nebenbei bin ich sehr  gespannt, wie es mit JAVA weiter geht http://goo.gl/rUAHG.

Vielleicht bekomme ich es doch noch mal hin, dass ich diese Jahr noch einen weiteren Post erstelle. Ich wollte seit Wochen mal was zu NDepend schreiben, aber …

Sonntag, Oktober 03, 2010

GIT, Putty and SSH auth (Windows)

Ich hatte heute morgen Problem beim Zugriff auf mein GIT-Repository. Eigentlich hatte es immer super geklappt, allerdings habe ich auf dem Rechner nur die Portable Version von msysgit benutzt. Also mal wieder das typische Googlen bis man was findet, etwas passendes zu finden, war aber eher ein Glücksspiel. Zumindest wußte ich zu 90% was ich zu tun habe.

Zu erst benötigt man natürlich GIT, unter Windows würde ich derzeit immer auf msysgit zurückgreifen. Außerdem werden für Zugriff auf Repositories mit SSH/Public Key Access noch die Putty-Tools benötigt, eigentlich braucht man nur pageant.exe, plink.exe und puttygen.exe.

Zuerst erzeugt man sich ein einen Private-Key mittels puttygen erzeugen. Nach dem das Zertifikat erstellt wurde, muss dieses nur noch gespeichert werden. A

PuttGen Interface after Key has been created.

Außerdem sollte man den Text für Public Key kopieren. Dieser wird für den Import bei dem GIT-Anbieter oder Server benötigt, genauso wie bei vielen anderen Applikationen. Bei Unfuddle zum Beispiel wird der Key beim Benutzer registriert und ermöglicht erst dadurch die Authentifizierung und den Zugriff auf das Repository.

Den gespeicherten Private-Key (ppk-Erweiterung) öffnen man nun mit pageant. Um den Key zu lesen muss die Passphrase angegeben werden.

pageant-opened

Ist der Key geöffnet, so kann man versuchen das Repository zu öffnen. Dazu "plink.exe –v git@<project>.unfuddle.com:user/<projectrepo>.git" ausführen. Die Antwort sollte dann etwa so aussehen:

   1: Looking up host "<project>.unfuddle.com"
   2: Connecting to 174.129.5.196 port 22
   3: Server version: SSH-2.0-OpenSSH_5.1p1 Debian-5
   4: We claim version: SSH-2.0-PuTTY_Release_0.60
   5: Using SSH protocol version 2
   6: Doing Diffie-Hellman group exchange
   7: Doing Diffie-Hellman key exchange with hash SHA-256
   8: Host key fingerprint is:
   9: ssh-rsa 2048 a6:74:33:36:95:31:6e:a6:d7:71:87:b8:3c:38:e2:60
  10: Initialised AES-256 SDCTR client->server encryption
  11: Initialised HMAC-SHA1 client->server MAC algorithm
  12: Initialised AES-256 SDCTR server->client encryption
  13: Initialised HMAC-SHA1 server->client MAC algorithm
  14: Pageant is running. Requesting keys.
  15: Pageant has 1 SSH-2 keys
  16: Using username "git".
  17: Trying Pageant key #0
  18: Remote debug message: Forced command: gitosis-serve <user>_<user>
  19: Remote debug message: Port forwarding disabled.
  20: Remote debug message: X11 forwarding disabled.
  21: Remote debug message: Agent forwarding disabled.
  22: Remote debug message: Pty allocation disabled.
  23: Authenticating with public key "<key comment>" from agent
  24:  
  25: Sending Pageant's response
  26: Remote debug message: Forced command: gitosis-serve <user>_<user>
  27: Remote debug message: Port forwarding disabled.
  28: Remote debug message: X11 forwarding disabled.
  29: Remote debug message: Agent forwarding disabled.
  30: Remote debug message: Pty allocation disabled.
  31: Access granted
  32: Opened channel for session
  33: Server refused to allocate pty
  34: Started a shell/command
  35: ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment.
  36: Server sent command exit status 1
  37: Disconnected: All channels closed

Evtl. kann eine Bestätigung des Server Keys notwendig sein, dass sollte allerdings nur beim 1. mal der Fall sein.

Hat der Teil geklappt, dann fehlt nur noch git korrekt zu konfigurieren. Hat mit den msysgit installer benutzt und die Option plink.exe während der Installation ausgewählt, so sollte bereits alles funktionieren, anderenfalls muss noch etwas nachgearbeitet werden. Um git beizubringen, dass er mittels pageant/plink sich authentifizieren soll, muss noch eine Umgebungsvariable gesetzt werden.

   1: GIT_SSH=<path to plink>\plink.exe

Anschließend kann mit git auf das Repo zugegriffen werden

Der Zugriff kann durch registrieren des Remote-Repo ordentlich verkürzt und vereinfacht werden. Beim erzeugen des Repo mit git clone … sollte das bereits passiert sein.

Hier noch mal ein kleiner Git-Ablauf (nach meinem Verständnis)

   1: cd myproject
   2: git init
   3: git remote add unfuddle git@<project>.unfuddle.com:<user>/<repo>.git
   4: git config remote.unfuddle.push refs/heads/master:refs/heads/master
   5: git pull unfuddle master
   6: git checkout -b dev
   7: ... changes ...
   8: git add **/*
   9: git commit -a -s -m ""
  10: git checkout master
  11: git merge dev
  12: git push unfuddle master

In der ersten Zeile wird in ein leeres Verzeichnis gewechselt und anschließend das Repository angelegt. Zeile 3 und 4 registrieren das Remote-Repository, so dass in Zeile 5 mit unfuddle auf dem Repo zugegriffen werden kann. Zum arbeiten wird dann in einen neuen Branch dev gewechselt. Anschließend können die Arbeiten durchgeführt werden. mittels git add werden neue Dateien für das Change-Tracking und den anschließenden Commit registriert. Mittels commit werden die Änderungen lokal übernommen. Der Parameter "-s" sorgt dabei für das hinzufügen des "Sign-off"/Abzeichnen und der Parameter –a übernimmt alle Änderungen in den Commit. Danach wird zum "Hochschieben" der Änderungen in den master gewechselt und die Änderungen aus dem "dev" Zweig übernommen. Git push shiebt in Zeile 12 die Änderungen ins Repository.

Weiterhin sind die Befehle git init/git gui zu empfehlen, ich nutze diese immer wieder mal. Manche Sachen sind einfach nicht geläufig.

Hier sind noch einige interessante Links:

Montag, August 23, 2010

Projektgeschäft …

Hmmm, mein letzter Post ist 3 Monate her. :( Sorry, habe ich in den letzten Wochen einfach viel mit meinem Projektbeschäftigt und hatte dann nicht mehr so viel Lust am Abend noch zu bloggen oder etwas anders zu machen. Zudem war das Wetter auch sehr schön, Fußball, ….

Ich werde versuchen in nächster Zeit wieder etwas mehr zu bloggen und auch einige Themen finden. Bisschen was habe ich noch an Ideen, aber Aufgrund von Lustlosigkeit nicht geblogged.

Aktuell habe ich eigentlich ein Projekt ohne "wow"-Effekt, dafür aber sehr anstrengend aufgrund der Konzeption. Ich finde es sehr schade, dass ich das Projekt nicht von Anfang an gestalten konnte, sondern ein "*****" weiterführen sollte. Schön ist es aber trotzdem jeden Tag wieder Lösungen zu finden.

Was sich auch bei diesem Projekt wieder zeigt, mit Continous Integration lässt sich die Qualität eines Projektes steigern, allein dadurch, dass das Vertrauen in die kompilierfähigkeit steigt. Wer wenige Erfahrungen mit Continous Integration hat, sollte sich mittels CI-Factory dem Thema zu nähern. CI-Factory setzt eine komplette Projektbuildumgbung mit allen wichtigen Tools und Konfiguration nach Best Practices auf. Ich bin nicht mit allen Sachen einverstanden, aber dabei handelt es sich um Details. Zusätzliche Aktionen, wie Code-Analysen oder Unit-Tests, sorgen für deutlich mehr vertrauen. Unit-Tests sind ein wichtiges Mittel, wie man auch immer wieder liest. Wir hatten innerhalb unseres Teams in den letzten Wochen mehrfach die Diskussion, was ein Unit-Test ist. Ich bin derzeit absolut der Meinung, dass ein Unit-Test komplett ohne äußere Einflüsse auskommen muss, zum einen beschleunigt dies die Ausführung, zum anderen sichert es einen wiederherstellbaren Ausführungszustand. Leider arbeiten wir mit VB.NET, ich finde es eine furchtbare Entscheidung und könnte während des Schreibens von Unit-Tests nur fluchen, obwohl es auch während der normalen Entwicklung schon ein "Krampf" ist. Leider hört man oft das Argument, dass sich die VB6-Entwickler nicht an etwas Neues gewöhnen müssen, aber mal ehrlich, VB6 und .NET sind schon sehr unterschiedliche Technologien.

Jeder der dennoch VB.NET-Projekte realisiert sollte darauf achten, dass Option Strict und Option Explicit auf jeden Fall aktiviert sind. Leider war das in meinem Projekt nicht der Fall, es gibt einige Ausführungspfade, wo ich nicht sagen kann, was wirklich bei den Typ-Umwandlungen passiert.

Eine andere Sache, die sich (wieder) sehr positiv gezeigt hat, sind DI/IoC. Dadurch wird die Wartung und Austauschbarkeit von Komponenten deutlich erhöht.

Nebenbei beschäftige ich mich wieder mit Prism/CompositeWPF. Ich finde das Konzept richtig schick und es macht viel Spaß damit zu arbeiten. Ich muss dabei noch so viel lernen, auch bei MVVM lerne ich bei jeder Benutzung wieder etwas dazu. Bei Prism gibt es demnächst ein neues Release (Version 4).

Dienstag, Juni 29, 2010

Ants Performance Profiler

Cool, es gibt die neue Version des Ants Performance Profilers. Neu in der Version ist eine Kommandozeilen Version, die im Build mitlaufen kann. Wenn man in einer Anwendung Performance Probleme hat, dann ist das sicherlich eines der besten Tools. Es ist leicht verständlich, schnell und einfahch zu benutzen. Ich finde jedes Team sollte Zugang zu mind. einer Ants Profiler Version haben. Die Investition in die Pro-Version rechnet sich und lohnt auf jeden Fall.

Sonntag, Juni 20, 2010

Oracle Client und die Versionen …

Leider muss ich schon wieder eine ganze Weile mit Oracle Datenbanken arbeiten. Es gibt sovieles, was mich an Oracle stört, aber ein Austauschen ist nicht möglich. Das Schlimmste bei der Arbeit mit Oracle-Datenbanken ist diese nervige Client-Problematik und diese TNSNames-Konfiguration Sch…. In dem Unternehmen in dem ich zur Zeit aktiv bin, gibt es ein relativ umfangreiches Software Management, man hat für Oracle eine Standardversion definiert, die Version 10. Leider gibt es zu der Version nicht den passenden ODP.NET Provider für .NET-Framework 2.0, so dass bisher den FX 1.0 Treiber benutzt wird. Wie man sich denken kann, wird dabei auch nicht alles unterstützt, unteranderem fehlt die Unterstützung für Framework 2.0 Transaktionen. Ein noch viel größeres Problem ist aber, dass es auch durchaus noch Arbeitsplätze mit Ora Client 9 gibt und auf diesen funktioniert es gar nicht. Bei manchen klappt es, wenn die OraOps10.dll vorhanden war, aber  dann ging es auch auf einigen Oracle Client 10 Installationen nicht.

Seit der Version 11, vielleicht auch 10 gibt es eine halbwegs akkzeptable Lösung, der Oracle Instant Client. Mit etwas Aufwand kann man sogar den Client komplett mit nur 5 Dateien mit der eigenen Applikation verteilen und ist nicht damit nicht mehr auf die vorhandene Installation, welche Version auch immer es ist, angewiesen. Nach dem ersten Schritt, finden des Instanat Clients als mögliche Lösungsoptionen, hatte ich mein Problem mit dem Oracle Client nocht nicht final gelöst. Laut Oracle müssen Umgebungsvars gesetzt werden, was dann aber evtl. höhere Rechte beim Einrichten erforderlich machen würde. Nach einigem googlen bin auch den Post "Deploying ODP.NET with Oracle Instant Client" gestoßen und das sieht genau nach der Lösung aus, die ich brauchte. Ich habe mich für den Basic Client entschieden, es gibt auch noch eine Lite-Version, ich wollte nicht das Risiko eingehen, dass Funktionalitäten nicht mehr gehen. (Lite würde ungefähr 30MB ergeben, Basic etwas über 100 MB) Die Dateien

  • oci.dll
  • Oracle.DataAccess.dll
  • oramts.dll
  • oramts11.dll
  • oramtsus.dll
  • orannzsbb11.dll
  • oraocci11.dll
  • oraociei11.dll und
  • OraOps11w.dll

müssen sich bei der Ausführung im Applikationsverzeichnis liegen. OraMTS wird für Transaktionen benötigt. Am besten im Visual Studio Projekt einbinden und "Copy to output directory" auf "Copy if newer" setzen, so dass die Dateie im richtigen Verzeichnis landen.

Einige Probleme gab es noch bei der Konfiguration auf den Rechnern, Oracle ermöglich es viele Einstellungen über Umgebungsvariablen oder Registry vorzunehmen, offensichtlich war durch die vielen Client Versionen auf meinem Rechner einiges "merkwürdig". Ich habe die Einstellungen für "NLS_LANG" und "TNS_ADMIN" in meiner Applikation gesetzt.

   1:  Environment.SetEnvironmentVariable("NLS_LANG", "GERMAN_GERMANY.WE8MSWIN1252")
   2:  Environment.SetEnvironmentVariable("TNS_ADMIN", AppDomain.CurrentDomain.BaseDirectory)

NLS_LANG bei Oracle nachschlagen. TNS_ADMIN ermöglich das Auffinder der TNSNAMES.ORA, ich konnte Transaktionen nicht ohne TNSNAMES aufbauen, es gab immer einen seltsamen Fehler, wenn die "Data Source" im Connection String den TNS-Eintrag enthielt. Nach dem beide Werte gesetzt waren, klappt es wunderbar, hoffentlich auch weiterhin. Vielleicht sollte sich Oracle mal überlegen, ob es nicht schick wäre einen komplett Managed Treiber zu erstellen.

Sonntag, Juni 06, 2010

Auto freier Sonntag – Fahrrad fahren in Berlin

Heute war, wie die letzten Tage, bestes Wetter. Zum Glück hat der ADFC heute zur Sternfahrt zum Umweltfest organisiert. Für mich war es die 1. Teilnahme und es war einfach nur schön, aber langsam.

Die Sternfahrt führt von vielen Punkten in Berlin zur Siegessäule, ich habe mich am Bahnhof Lichtenberg angschlossen, obwohl auch vor der Haustür möglich gewesen werden. Es war super beeindruckend, wie viele schon an in der Schlange waren. Unterwegs Richtung Ostbahnhof haben sich viele weitere Radler angeschlossen und bei gemütlichem Tempo, vermutlich knapp über 10km/h fuhr es sich auch bei der Hitze super. Die Tour führte anschließend über Treptow nach Neuköln, dort war eines der Highlights der Tour, fahren durch den Autobahntunnel. Allerdings vor dem Tunnel war das große warten. Die Massen waren so große, dass es eine Gefühlte Ewigkeit gedauert hat, um auf die Autobahn zu kommen. Im hinteren Teil konnte man anschließend kräftig gas geben um wieder nach Vorne zu kommen. Im Tunnel auf der Autobahn war es so klasse, zu mal bei den Temperaturen der Schatten nach dem Stehen in der Hitze super angenehm war. Toll war im 2. Teil der Strecke, dass diese komplett durch die Polizei gesperrt war, der 1. Teil war Fahren hinter dem Führungsfahrzeug. Irgendwo kam auch der ganze Rest der Radler aus den westlichen Bezirken dazu, das war aber nicht mehr so sehr zu merken, da sich alles über viele viele Kilometer auseinander gezogen hatte.

Slideshow

Auf dem 17. Juni wurden die Radler Umweltfest begrüßt, wo Essen und Getränke nach gefüllt werden konnten. Bei Getränkenn fällt mir ein, dass meine 1,5-2l knapp waren. Auf dem Umweltfest gab es auch noch gute Musik, unter anderem von 48 Stunden. Ich habe mir dort nicht so viel Zeit gegönnt, bin nach kurzem Aufenthalt Richtung zu Hause gefahren.

Für mich war es ein Fahrradreiches Wochenende mit viel Sonne und viel Spass, leider aber auch wieder ein Blog-Post ohne Technik. Wenn es gut läuft kann ich vielleicht nächstes Jahr die Kids und einige Freunde begeistern. Es waren sehr viele Kinder dabei.

Sonntag, Mai 30, 2010

NVidia Treiber Aktualisierung (Win7)

Eigentlich wollte ich letzte Woche Donnerstag mal ein bisschen was bloggen, allerdings hat mich mein Rechner geärgert. Unter Umständen habe ich einen Bluescreen, HP empfiehlt den Grafikkarten-Treiber zu aktualisieren. Da hatte ich mir nichts böses bei Gedacht und einfach mal den aktuellen (schon 2 Versionen) von der HP-Seite heruntergeladen. Treiber installiert und dann das große Wundern, nach einem Neustart erschien kein Login-Window, nur ein schwarzer Bildschirm immerhin mit Mauszeiger. Dann ging das große Rätseln los, was denn das? Da ich unterwegs war, konnte ich auch nicht an einem anderen Rechner googlen, also versuchte ich in den Abgesicherten Modus zu booten. Im Abgesicherten Modus mit einem BitLocker geschützten System, muss der Recovery-Key eingegeben werden, ansonsten ist kein Booten möglich. Den Key hatte ich natürlich nicht, aber unser IT-Dienstleister, zum Glück ist der meistens erreichbar, so dass nach einigen Minuten der Key kam. Aber zum Erschrecken war das gleiche Verhalten auch im abgesicherten Modus vorhanden. Ich habe mehrere male gebootet und nach dem Modus gesucht, wo man wählen konnte, welche Treiber geladen werden sollen. Alles booten in den abgesichtern Modus half nichts. Der versuch “Last Known Good” zu booten, änderte auch nichts, so dass das Suchen nach einer Windows DVD los ging. Man kann nur mit einer Windows DVD oder mit einer Windows Rettungs DVD System Restore aktivieren und einen alten Zustand zurückrollen.

Gott sei Dank, wurde von Microsoft seit Vista System Restore als Komponente mitgeliefert. Ach wichtig ist natürlich, dass System Restore aktiviert ist. Wer nicht sichert ist, ob es aktiv ist, sollte es prüfen. Dazu ”Control Panel\System and Security\System” öffnen und anschließend “Advanced system settings” öffnen. Der Tab “System Protection” enthält die hilfreichen Funktionen. Wenn neben dem Laufwerk unter “Protection” “On” steht, dann sieht es gut. Man kann für das Laufwerk den maximal nutzbaren Speicherregeln und noch einiges mehr.

System Properties\System RestoreBei der Ausführung von MSI-Installation werden durch Windows automatisch Restore Points angelegt, so dass anschließend ggf. die Installation komplett zurückgerollt werden kann. In meinem Fall habe musste ich den Eintrag vor der Treiber Installation wählen.  Leider kann man System Restore nur mit einer DVD oder im gestarteten Windows (siehe Screenshot “System Restore”) durchführen, aber ansonsten eine super Sache.

Nach dem zurücksetzen hatte ich immer noch einige Probleme, aber nach und nach ist das System wieder Ok, hoffe ich. Meine Empfehlung, System Restore aktivieren und im Hintergrund mitlaufen lassen.

Montag, Mai 03, 2010

Oracle Batch Operation

Ich hatte mich letzte Woche bei einer Anwendung mit der Geschwindigkeit bei Datenbankoperationen beschäftigt. Die Anwendung schreibt etwa 100 Datensätze in einer große Tabelle mit ca. 60 Mio Datensätzen. Beim einfügen der Daten musste ich leider 20s warten, was für mein Verständnis für Datenbankzugriffe einfach nichz akzeptabel ist. Demzufolge habe ich die Gründe untersucht.

  1. Werden alle Daten in einer Transaktion geschrieben. In dem Thema verbirgt sich eine etwas heßliche Problemstellung. Die Oracle-Clientversion ist so eine seltsame Version, dass ich kein ODP.NET Treiber bekomme, der ohne Client-Neuinstallation arbeitet. Ich habe keine Möglichkeit die Ora-Client-Installation auf den Zielsystemen zu verändern. Um meine Absichten deutlich zu machen, habe ich trotz des Bewußtseins, dass es nicht funktioniert den TransactionScope benutzt. Im Anschluss die manuelle “old-style” Transaction geöffnet, IDbConnection.BeginTransaction.
  2. Trigger auf der Tabelle prüfen. Trigger verlangsamen die Ausführung der Änderungsoptionen und könnten schon einen negativen Effekt erklären.
  3. Indizes beeinflußen die Geschwindigkeit von Änderungsoperationen ebenso, so dass diese auch geprüft werden sollten.
  4. Andere Abhängige Datenbankobjekte prüfen, z. B. Materialized views (Snapshots).

Nunja, da ich mich mit der Anwendungsprogrammierung deutlich besser auskenne als in der DB-Programmierung, habe ich mich mit dem ersten Punkt beschäftigt. Meine Transaktionen waren vorhanden, aber die Geschwindigkeit war immer noch nicht befriedigend. Also die Idee eines Kollegen aufgegriffen, einen PL/SQL aus meinen Operationen zu erstellen. Bei der Ausführung eines PL/SQL-statements wird dieses durch die DB optimiert und als ein Block  übergeben, evtl. greifen auch einige zusätzliche Optimierungen. PL/SQL-Blöcke beginnen mit “BEGIN” und Enden mit “END”. Um den Befehl aus dem .NET-Framework über den ODP-Provider zu übergeben, müssen alle Anweisungen in einer Zeile aufgeführt werden. Zum Beispiel: BEGIN Stmt1; Stmt2; … END; Nach all der Mühe war ich von dem Ergebnis enttäucht. Es gab eine Verbesserung, allerdings nur maginal. Es gab auch nix an Triggern, die ich hätte verantwortlich machen können.

Allerdings gabe es 3 Indizes, 1 PK und 2 Indizes, bei einer 4 Spalten-Tabelle. Die Wahrscheinlichkeit ist sehr hoch, dass bei den Abfragen die definierten Indizes genutzt werden, so dass ich mich nicht daran zu schaffen machen wollte. Ein Kollege meinte zu dem, dass die Berechnung der Indizes nicht die Operation merklich beeinflußt.

Blieb nur noch der Punkt 4., es gibt 4 MVs, 2 werden OnDemand aktualisiert, 2 werden OnCommit (fast) aktualisiert. Also der Versuch alle Views mittels Demand von Operationen auf der Tabelle abzuklemmen. Oh Wunder, von 20s auf unter 1s, dass sind schon Zahlen, die ich für 100 einfüge Operationen in eine große Tabelle erträglich finde. Das Aktualisieren der Views wird durch einen seperaten Aufruf am Ende der Verarbeitung angetriggert und dauert einige Sekunden, allerdings weniger, als 100 Inserts mit Daueraktualisierng. MVs haben viele Vorteile, gerade beim Abfragen der Daten und könen die Performance von Abfragen um ein vielfaches Steigern. Wie aber auch geschehen, können andere Operationen verlangsamt werden.

Sonntag, April 25, 2010

ASP.NET SQL Membership database schema

AAAAAhhhh!!!

Mir war mal wieder nach Fluchen, als ich eine ASP.NET DB mit dem SQL-Express als File DB angelegt hatte. Ich konnte das Schema mit “ASPNET_REGSQL” nicht anlegen. Irgendwie ist es doof gemacht, dass das Tool nicht die Möglichkeit bietet auf eine File-DB zu zugreifen. Zugriff über das im SQL Server (Express) gemountet File ist eigentlich auch nicht so schwer, wenn manweiß wie, aber…

Ich habe den Weg direkt über ASPNET_REGSQL versucht und auch über SQL Server Management Studio und dann AttachDB. Beide Wege führten zu einem “Unable to attach physical file …” Operation System Error 5 --- WAS? Eigentlich könnte man den Fehler mit keine/zu wenig Rechte auf der Datei. Ich glaube, man muss auf dem Verzeichnis “Full Control” für den Dienst Nutzer vergeben. Ich habe es noch einfach gemacht, einfach “Everyone” auf FullControl für mein Projektverzeichnis.

Anschließend ASPNET_REGSQL starten. Auf der 2. Seite als Server “.\SQLEXPRESS” eingeben und den kompletten Pfad zum MDF-File.

image Anschließend nur noch warten und das Schema ist erstellt. Schade, dass es nicht aus dem Studio einfach durch einen klick auf die DB geht. (auch in VS 2010 nicht)

Auf jeden Fall habe ich nun mein Datenbank-Schema und kann mich weiter mit OpenID beschäftigen, denn ich will gar kein SqlMembership. ;) Ich bin der Meinung, dass Passwortverwaltung auf der eigenen Website gestern war. Dazu kommt bestimmt demnächst auch mehr.

SQL Server 2008 R2 Released? – Office 2010

Laut Microsoft Newsletter gibt es das neue Release des SQL Servers, also ab zu Technet/MSDN. Nur leider war ich sehr enttäucht, dass es nur CTPs für den R2 gab. Komisch aber am 21.4. war das Launch-Event. Dann muss ich leider noch warten, bis ich das neue Release installieren kann, Express, Management Studio.

Als Alternative gab es dafür bereits für Technet/MSDN Abbonennten Office 2010 zum Download. Den download habe ich dann natürlich sofort angeschmissen. Anschließend habe ich 1-2h überlegt, ob ich es installieren sollte. Wie sich die meisten denken können, ich habe das neue Office installiert. Ich muss sagen, dass es schon schick, anders aussieht. Ich freue mich jetzt schon auf die Conversation-View im Outlook, ich bin die Anzeige in Threads schon so aus Google gewöhnt, dass ich es dieses Feature im Outlook vermisst habe. Bei allen Office-Applikationen hat sich mal wieder das Ribbon verändert.

imageAls Entwickler ist das schon …. Zum einen fand ich diesen Buuble oben-links sehr ansprechend, zum anderen hat es bei der Entwicklung etwas genervt.

Dann hoffe ich mal auf den baldigen SQL Server Download.

Sonntag, März 21, 2010

SharePoint deployment

Letzte Woche wurde durch einige meiner Kollegen das erste CodePlex-Projekt unserer Firma veröffentlicht. Das Projekt XML based Content Deployment in SharePoint beschäftigt sich mit der Veröffentlichung von SharePoint-Projekten und –Artefakten. Das Projekt ist ein Ergebnis unserer Erfahrungen bei der Entwicklung und Veröffentlichung von SharePoint-Projekten und wird in Kundenprojekten verwendet. Soviel kann ich leider nicht zu dem Projekt sagen, da ich an dem Projekt nicht beteiligt bin und bisher kein Deployment mit dem Projekt gemacht habe. Die Verwendung des Projektes ist meines Wissens nicht eingeschränkt und kann beliebig verwendet werden, bitte trotzdem das Licence agreement beachten. Feedback zum Projekt wäre schön, bitte nutzt dafür den Diskussionsbereich.

Sonntag, März 14, 2010

Applikationsperformance

PPPuuuhhh, die Woche wurden größere Probleme mit der Performance festgestellt. Das Problem war so Akut, dass dringend gehandelt werden musste.

Um die Performance einer Anwendung zu verbessern muss man immer wieder messen, was wie lange braucht. Bei den Problemen, die bei uns aufgetreten sind, sind alle Schichten/Anwendungskomponenten involviert, so dass eine Fehlersuche nicht das einfachste ist. Simple Messung der Zeiten an bestimmten Punkten ist meistens schon genug. Ein ganzes Stück schicker geht es mit einem Profiler. Beim Messen musste ich feststellen, dass es überall nicht optimal läuft. Beim Client dauerte das Aufbereiten der Eingaben schon ewig, im Service brauchte das Speichern viel Zeit bei der Übergabe an die DB und noch schlimmer war die Verarbeitung in der DB.

Die Verarbeitungszeit im Service war nicht so tragisch, allerdings auch störend. Uns war bereits bei der Realisierung bewusst, dass das Speichern mit Linq to Sql bei Massendaten nicht optimal läuft, trotzdem wir schon einige Optimierungen genutzt haben. Der letzte Optmierungsschritt für die L2S-Verarbeitung war die Übergabe an die DB vorbei durchzuführen. Im letzten Jahr hatten wir in einem anderen Projekt bereits ähnliche Optimierung durchgeführt, allerdings habe ich diesmal einen anderen Weg, vermutlich effektiveren Weg gewählt, die Daten werden mittels Table-Valued Parametern übergeben, dadurch is eine einfache Übergabe der Massendaten möglich. Ein super Einführung in das Thema mit Beispielen für die .Net-Realisierung gibt es unter http://www.sommarskog.se/arrays-in-sql-2008.html. Letztendlich muss man einen eigenen Type im Sql-Server erstellen, optional eine Stored Procedure anlegen, bei mir enthält sie Insert/Update/Delete und anschließend im .NET-Code eine DataTable mit den Feldern des SqlServer Types anlegen und den Parameter konfigurieren. Beim Parameter muss der TypeName gesetzt werden, sowie der SqlDbType auf Structure.

Diese Optimierung entspannte die Lösung schon um einiges, aber weiterhin festzustellen war, dauerte die Ausführung in der DB immer noch viel zu lange. Bei aktivierten Triggern in der DB dauerte die Verarbeitung mehrere Minuten, ohne Trigger 10s. Für das Problem haben wir bisher noch keine Lösung, dies ist ein akuter Eingriff in das Verarbeitungsverhalten unserer DB. Ich bin überhaupt kein Freund von Triggern und bin auch der Meinung, dass Trigger versteckte DB-Logik sind. Vermutlich muss die gesamte Trigger-Verarbeitung herausgelöst werden.

Im Client war der Code nicht optimal, allerdings nun auch nicht so ineffektiv, allerdings für den Fall traten 20000 Aufrufe auf einen Code-Block auf, der Xml-Verarbeitung durchführte. 20000-Aufrufe in 3-4min, ungefähr 100 Aufrufe pro Sekunde, sind zu langsam und zum Teil für den Benutzer nur schwer nachzuvollziehen. Das Ergebnis wurde auch durch die Trial-Version von RedGates ANTS Profiler bestätigt. Die Optimierungen durchzuführen vielen mir relativ schwierig, so dass ich einen Kollegen gebeten habe, einfach den Code mal mit mir durchzusehen und Anmerkungen abzugeben. Die Fragen und Anregen waren sehr effektiv, so dass die Geschwindigkeit verdreifacht wurde. Eigentlich waren es ganz einfache Sachen, versuchen Type-Konvertierungen zu vermeiden, die 2. Xml-Verarbeitung reduzieren. Eine andere kleinere Optimierung war die Anpassung des XPaths, statt “//” (decendant-or-self) in der Abfrage zu verwenden, wird nun der XPath voll angegeben. Des Weiteren habe ich das Konvertierungsergebnis bei Type-Konvertierungen gespeichert und für eine erneute Konvertierung gespeichert, ob das sich als Vorteil im regulären Betrieb erweist, muss sich noch zeigen. Mit allen Optimierungen ist der Client bis 4 mal schneller, allerdings vermutlich nur unter Entwicklerbedingungen (wenige unterschiedliche Werte). Allerdings bringt auch das Release-Compile durch Inlining evtl. noch einige kleinere Vorteile.

Die Optimierung in Service und Client sind extrem wichtig und sollen die Nutzbarkeit deutlich verbessern, allerdings ohne eine Anpassung in unserer Datenbank, werden die Ergebnisse nichts bringen, da unsere Trigger noch immer zu viel Zeit verschlingen. Also noch einmal Ideen sammeln, wie wir das Problem reduzieren können.

Hoffentlich wieder mehr Zeit

Ich habe die vergangenen Wochen das bloggen komplett vernachlässigt. Grund für die Vernachlässigung waren massig Tätigkeiten im Job, ich musste noch “alte” Aufgaben aus 2009 erledigen, zu dem lief es in einem Projekt nicht rund. Das Problem waren im Projekt halt die Ressourcen und die Anzahl der Tätigkeiten, die noch zu tun waren.

Einiges kommt in den nächsten Wochen noch auf mich zu, im Unterschied zu sonst sind es einige größere Private-Events. Allerdings bin ich mal ich die nächsten Wochen auf Dienstreise und muss die Zeit im Hotel verbringen.

Freitag, Januar 15, 2010

jQuery 1.4 verfügbar

Ich habe gerade festgestellt, dass endlich das finale Release von jQuery 1.4 verfügbar ist.

Es hat sich einiges getan, mal wieder soll es deutlich schneller gehen und viele, viele Verbesserung bei der Programmierung. Ich habe noch einiges zu lesen heute. Ich freue mich schon auf den nächsten Einsatz von jQuery bei der Entwicklung.

Download unter: http://jquery.com/ oder 14 Days of jQuery

Freitag, Januar 01, 2010

Happy New Year

Nun ist schon fast der 1. Tag des Jahres vorbei, ich habe bisher noch nicht mal einen Rückblick auf das alte Jahr gepostet.

2009

In 2009 war fast alles mit einem Projekt vollgepackt. Das Projekt hat Spaß gemacht und war auch sehr interessant, sowohl menschlich als auch technologisch. Vielleicht bleibt der Kontakt mit den Kollegen bestehen, freuen würde es mich. Ein weiterer Vorteil des Projektes war die Lage, es war in Berlin und erforderte somit wenig Reiseaufwand, zu dem war ich nicht so abhängig von der DB. Leider muss ich auch sagen, dass in 2009 viele Kontakte zu “alten” Kollegen noch weniger geworden sind.

Die letzten Tage des Jahres habe ich mal fast komplett ohne Arbeit verbracht. Mal 1h um einen Kollegen zu helfen, ansonsten den Rechner nicht für Arbeit benutzt. Es war wirklich Zeit, dass ich mal entspannen konnte, pünktlich zum Urlaub kam eine kurze Krankheit dazu, die mich 1,5 Tage ziemlich belastet hatte, aber dann war alles wie weg geblasen. Die restlichen Tage habe ich mit Familie und Freunden verbracht. Etwas Stress kam dann für die Silvestervorbereitungen auf, nach dem wir keine bessere Idee gefunden haben, war wieder Raclette-Abend angesagt. Das Beste an den letzten Tagen des Jahres war das schöne Schneewetter. Die letzten Stunden waren richtig schön und auch die ersten Stunden haben viel Spaß gemacht, der Rest des ersten Tages war dann eher Dösen und Erholen.

Bloggen habe ich 2009 irgendwie nicht wie erwünscht auf die Reihe bekommen. Vielleicht wird es 2010 wieder regelmäßiger. Allerdings ohne entsprechende Themen kann man nix bloggen.

2010

Ich bin sehr gespannt, was das Jahr 2010 bringen wird. Im Gegesatz zum letzten Jahr, ist dieses Jahr wieder alles offen was das Projektgeschäft bei mir betrifft. Ich muss leider noch einige ältere Projekte abschließen, aber was dann …

Technologisch wird mit .NET 4.0, VS2010 und die Office 2010 Produkte wieder einiges Neues von Microsoft kommen, ob es direkt Auswirkungen in die aktuelle Arbeit bringen wird, bleibt abzuwarten. Als Entwickler möchte man natürlich immer das Neueste nutzen, aber nicht immer ist das auch sinnvoll. *leider*

Vielleicht ist Jahr 2010 auch ein Jahr von Veränderungen, keine Ahnung, einfach mal schauen. Einige Veränderungen bringt uns die neue „tolle“ Regierung, aber nutzen sie uns?