Laden...

NHibernate Transaction verständnissfrage.

Erstellt von Fracoon vor 16 Jahren Letzter Beitrag vor 16 Jahren 1.372 Views
F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren
NHibernate Transaction verständnissfrage.

verwendetes Datenbanksystem: postgres

Hi@all,

hab da mal ne Frage:

Kann eine NHibernate ISession immer nur eine ITransaction verwalten? Hab über google schon verschieden Aussagen gefunden. Aber nichts eindeutiges.

Wenn mehrere gehen sollten, wie kann ich dann festlegen was in welcher Transaction ausgeführt wird? (Schon alleine desswegen geh ich davon aus das es generel nicht geht??!)

F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren

vieleicht noch ergänzend warum ich das frage:

Das datenbankeigene Locking funktioniert immer nur innerhalb einer Transaktion(oder?)

Ich würde es in meiner Applikation gerne verwenden habe jedoch nur eine Globale Session (Singleton)

Wenn ich jetzt mehrere z.B. Kunden zum bearbeiten öffne bräuchte ich ja mehrere Transaktionen damit das Locking funktioniert?!?!

F
10.010 Beiträge seit 2004
vor 16 Jahren

Tja, da hast du dann aber schon ein kleines Designproblem.

Sowohl NHibernate, als auch alle auf ADO.NET aufbauenden Pattern sind auf
den disconnected Betrieb ausgerichtet.

D.h. es werden beim bearbeiten keine Datensätze gelockt.
Wenn man das früher getan hat, dann war das mit erheblichen Performanceeinbussen verbunden, und kann zu erheblichen problemen führen.

Unter ADO.NET und auch bei NHibernate fängt man beim Speichern eine
concurency Exception ab, die angibt, das sich der Datensatz zwischenzeitlich geändert hat.

Anders ist es bei zusammengehörigen Aktionen ( z.b. Orders und Orderdetails ),
die kann/sollte man mit Transaktionen einrahmen.

F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren

Ok, hab mitlerweile die "versionierung" vin nhibernate eingebunden. funktioniert gut.

Aber für einen Endanwender wäre es natürlich unschön wenn er viele änderungen vornimmt, um dann festzustellen, dass er nicht speichern kann weil eine concurency Exception auftritt.

Wie geht man damit um? Muss ich für alle verschiedenen Datensätze die man Speichern kann eine "vergleichsroutine" schreiben bei der man dann die differenzen sehen und dementsprechend reagieren kann?
Oder kann man sowas generisch für alle schreiben irgendwie?

Finde die Lösung mit der concurency Exception zwar gut, für den Endanwender in gewissen Fällen aber eher unschön.

Wie kann man sowas handhaben?

F
10.010 Beiträge seit 2004
vor 16 Jahren

Tja, gute frage.

Ich lese dann den neuen Datensatz ein, habe für meinen ORMapper dann eine Funktion, die generisch
die Objekte vergleicht, und mir eine Liste der Änderungen bietet.

Die kann ich dann ganz oder je nach Wunsch teilweise ausgeben.

Da ich in jedem Datensatz ein LastChangedBy habe, kann ich auch den
Benutzernamen ausgeben, durch den die Änderungen pasiert sind, und ein
überschreiben erfragen.

F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren

Tja, gute frage.
Ich lese dann den neuen Datensatz ein, habe für meinen ORMapper dann eine Funktion, die generisch
die Objekte vergleicht, und mir eine Liste der Änderungen bietet.
Die kann ich dann ganz oder je nach Wunsch teilweise ausgeben.

hört sich interessant an!! Mir (als "Anfänger") drängt sich jedoch die Frage auf :

Wie kann ich für VERSCHIEDENE Objekte/Klassen generisch die Attribute vergleichen? Ohne diese in der generischen funktion angeben zu müssen? Hast vieleicht nen Link? oder Codeschnippsel für mich?

F
10.010 Beiträge seit 2004
vor 16 Jahren

Das verfahren geht bei mir, weil der ORMapper sowieso schon zugriff auf
die zu speichernden Daten hat, denn er muss die objekte ja auch befüllen können.

Amsonsten geht es "einfach" per reflektion.

F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren
In etwa so?

Hab mir das ganze jetzt mal o zurecht gelegt :


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            test org = new test();
            test db = new test();
            test changed = new test();

            org.Id = 1;
            org.Nachname = "BlaBLubb";
            org.Name = "Hans";

            db.Id = 1;
            db.Nachname = "Mustermann";
            db.Name = "Hans";

            changed.Id = 1;
            changed.Nachname = "Wurst";
            changed.Name = "Hans";
            
            Type t = typeof(test);

            foreach (System.Reflection.PropertyInfo pi in t.GetProperties())
            {
                
                Console.WriteLine(pi.Name + " | " + pi.PropertyType);
                Console.WriteLine("Original   : " + pi.GetValue(org, null).ToString());
                Console.WriteLine("DB-Value   : " + pi.GetValue(db, null).ToString());
                Console.WriteLine("Your-Value : " + pi.GetValue(changed, null).ToString());
                Console.WriteLine();
            }

            Console.ReadLine();

        }
    }

    class test
    {
        private int id;

        public int Id
        {
            get { return id; }
            set { id = value; }
        }
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        private string nachname;

        public string Nachname
        {
            get { return nachname; }
            set { nachname = value; }
        }
    }
}

sieht eigentlich ganz net aus. Wenn ich das jetzt in eine Funktion packe die 3 Objecte entgegennimmt könnte ich mir ja aufgrund der einzellnen Typen eine GUI generieren lassen (String,Integer = Textbox,Bool = Checkbox)
In der könnte man dann alle 3 Versionen des objects anzeigen und den Benutzer entscheiden lassen was er tut.

Klingt gut oder?

F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren

ok eine Sache ist mir jetzt noch aufgefallen. Mit dieser Methode bekomme ich immer alle Properties. Macht ja nicht unbedingt immer sinn, weil manche Properties durch den Benutzer gar nicht geändert werden können. Kann ich properties in einer Klasse "Markieren" um diese Markierung später auszuwerten?

Also ob das Attribut im Vergleich angezeigt werden soll oder nicht?!?!

F
10.010 Beiträge seit 2004
vor 16 Jahren

Natürlich.
Attribut selber erzeugen, das Property damit decorieren, und dann
per reflection die Attribute des Properties abfragen.

F
Fracoon Themenstarter:in
85 Beiträge seit 2007
vor 16 Jahren
Danke

Vielen Dank FZelle für dein endloses Engagement. 👍

Meine Frage ist damit vorerst mal beantwortet. Ich werde wahrscheinlich in meinem Lernprozess auf noch viele andere Fragen stoßen und freue mich, dass es einen Ort wie diesen hier gibt!!