Announcement

Collapse
No announcement yet.

Nhibernate - Out of Memory Exception

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Nhibernate - Out of Memory Exception

    Hallo,

    ich nutze für die Speicherung von meinen Daten NHibernate. Leider habe ich hin und wieder auch mit grösseren Datenmengen zu tun.

    Mit NHibernate bekomme ich aber immer eine "Out of Memory-Exception". Ich weiss langsam nicht mehr, was ich noch tun soll. Eigentlich sind doch 1.000 Datensatze nicht so viel...

    Code:
            public static void SaveCountedDataToDatabase(object data)
            {
                if (!_initDone)
                    Init();
    
                using (ISession session = NHibernateHelper.OpenSession())
                {
                    using (ITransaction transaction = session.BeginTransaction())
                    {
                        session.SaveOrUpdate(data);
    
                        transaction.Commit();
                    }
                }
            }
    
            public static void SaveCountedDataListToDatabase(List<CountedDataBase> data)
            {
                if (!_initDone)
                    Init();
    
                int count = 0;
                int next = 1;
                ISession session = NHibernateHelper.OpenSession();
                ITransaction transaction = session.BeginTransaction();
                for (int i = count; count <= data.Count; i++ )
                {
                    if (i == next * 1000)
                    {
                        transaction.Commit();
                        session = NHibernateHelper.OpenSession();
                        transaction = session.BeginTransaction();
                        next++;
                    }
    
                    session.SaveOrUpdate(data[i]);
                }
    
                transaction.Commit();
            }
    Beide Methoden lösen eine Exception aus. Die eine früher, die andere später. Insgesamt muss ich ca. 1.000.000 Datensätze durchschleusen. Bei max. 20.000 ist aber spätestens bei beiden Schluss...

    Code:
        public class CountedDataBase
        {
            #region Properties
    
            public virtual int VehjNo { get; set; }
            public virtual int IndexVehjNo { get; set; }
            public virtual int IndexVisum { get; set; }
            public virtual int Id { get; set; }
            public virtual int PeriodId { get; set; }
            public virtual int PeriodOperatingDayId { get; set; }
            public virtual int StopNo { get; set; }
            public virtual string StopCode { get; set; }
            public virtual int StopPointNo { get; set; }
            /// <summary>
            /// Referenz 1.1.1970
            /// </summary>
            public virtual int VehjDate { get; set; }
            public virtual int CurrentDeparture { get; set; }
            public virtual int Departure { get; set; }
            public virtual double Board { get; set; }
            public virtual double Alight { get; set; }
            public virtual double Occupation1 { get; set; }
            public virtual double Occupation2 { get; set; }
            public virtual double Capacity1 { get; set; }
            public virtual double Capacity2 { get; set; }
    
            #endregion
    }
    Mapping:
    Code:
      <class name="CountedDataBase" table="counteddata" lazy="false">
        
        <composite-id>
        	<key-property column="VehjNo" type="Int32" name="VehjNo" />
        	<key-property column="IndexVehjNo" type="Int32" name="IndexVehjNo" />
        	<key-property column="PeriodId" type="Int32" name="PeriodId" />
        	<key-property column="VehjDate" type="Int32" name="VehjDate" />
        </composite-id>
        
        
        <property name="IndexVisum" type="Int32" />
        <property name="PeriodOperatingDayId" type="Int32" />
        <property name="StopNo" type="Int32" />
        <property name="StopCode" type="String" />
        <property name="StopPointNo" type="Int32" />
        <property name="CurrentDeparture" type="Int32" />
        <property name="Departure" type="Int32" />
        <property name="Board" type="Double" />
        <property name="Alight" type="Double" />
        <property name="Occupation1" type="Double" />
        <property name="Occupation2" type="Double" />
        <property name="Capacity1" type="Double" />
        <property name="Capacity2" type="Double" />

    Hat jemand eine Idee wie ich die Daten in die Datenbank bekomme? Ich denke NHibernate sollte das doch hinbekommen...


    Vielen Dank für Eure Hilfe,
    Tucca

  • #2
    Wenn du zu dem gezeigten Code kommst befinden sich bereits alle (1.000.000) Datensätze in der data List?

    Was sagt den der Stack wenn die Exception auftritt? Kommt die Exception wirklich aus NHibernate oder doch eher aus ADO.Net oder deinem Code.

    Code:
    if (i == next * 1000)
    Code hat sich keinen Zusammenhang zu deinem Problem aber den Teil mit der next Hilfsvariablen finde ich trotzdem merkwürdig. Ich vermute du willst jeden tausendsten Datensatz commiten dann reicht

    [CODE]if ((i % 1000) == 0)[CODE]

    % ist der Modulo Operator.

    Comment


    • #3
      Hi,

      vielen dank für die schnelle Antwort.

      Ja zu dem Zeitpunkt des Speicherns befinden sich alle Datensätze im Speicher, da ich sie vorher schon bearbeiten muss. Da hab ich aber auch noch keine Probleme.
      Die Hilfsschleife war nur gedacht, um die Daten in "Paketen" zu speichern... Ich hatte gehofft, damit notfalls die Variablen löschen zu können.

      Es könnte natürlich auch ADO.NET sein das Problem. Muss ich mal schauen... Danke für den Hinweis.


      Gruß,
      Tucca

      Comment


      • #4
        Ja zu dem Zeitpunkt des Speicherns befinden sich alle Datensätze im Speicher, da ich sie vorher schon bearbeiten muss. Da hab ich aber auch noch keine Probleme.
        Ich könnte mir vorstellen das während dem speichern erstmal eine Kopie der zu speichernden Daten erstellt wird(habe keine Erfahrung mit NHibernate ist also nur eine Vermutung). Mit 1.000.000 Datensätze hast du vielleicht noch keine Probleme mit der doppelten Menge dann aber schon. Wenn möglich solltest du probieren die nicht alle Gleichzeit im Speicher zu halten. Sondern verarbeiten und speichern gemeinsam in kleinere Blöcke zu zerlegen.

        Comment


        • #5
          Die Frage ist natürlich ob ein O/R-Mapper für einen solchen Einsatz konzipiert ist. Ich denke wenn man wirklich Massendaten hat, und ich glaube bei 1.000.000 Datensätzen kann man wirklich davon reden, dann würde sich vielleicht eher ein BULK INSERT oder ähnliches lohnen. Dort werden die Daten in bestimmter Formatierung in eine Datei geschrieben und der Datenbank diese Datei zugreifbar gemacht. Die Daten werden direkt über die Datei in die DB eingefügt. 1 Mio INSERTS sind wahrscheinlich auch nicht sehr performant wenns evtl. auch noch übers Netz geht.

          Comment

          Working...
          X