Anna Sałacińska 1 Napisano 21 Listopada 2023 Udostępnij Napisano 21 Listopada 2023 w Błąd 0x80040E31 przy dodawaniu kontrahenta Dzień dobry, mam program dodający zk przez sferę, w celu dodania tego zk wykonuję następujące kroki: Sprawdzam czy kontrahent istnieje jeśli nie istnieje dodaje nowego InsERT.Kontrahent kon = this.sfera.sgt.Kontrahenci.Dodaj(); kon.Typ = 0; kon.Symbol = ".."; kon.Miejscowosc = ".."; kon.Ulica = ".."; kon.Telefony.Dodaj(".."); kon.Zapisz(); kon.Zamknij(); Jeśli istnieje to wczytuję po id i aktualizuję InsERT.Kontrahent kon = this.sfera.sgt.Kontrahenci.Wczytaj(ID); kon.Miejscowosc = ".."; kon.Ulica = ".."; kon.NrDomu = ".."; if (kon.Telefony.Liczba == 0) { kon.Telefony.Dodaj(".."); } else { kon.Telefony[1].Numer = ".."; } kon.Zapisz(); kon.Zamknij(); Następnie dodaje zk dla tego kontrahenta zk = this.sfera.sgt.SuDokumentyManager.DodajZK(); zk.UwagiExt = ".."; zk.NumerOryginalny = ".."; zk.Podtytul = "..."; zk.StatusDokumentu = 6; zk.KontrahentId = kontrahentId; zk.Zapisz(); zk.Zamknij(); I to działa ale czym dłużej działa serwer tym częściej mam błędy 0x80040E31 Cytat System.Runtime.InteropServices.COMException: Wyjątek od HRESULT: 0x80040E31\r\n w InsERT.Kontrahent.Zapisz() Błąd pojawia się dla nowych kontrahentów i tych edytowanych, dodatkowo dla tych edytowanych przed wczytaniem do edycji sprawdzam tabelę ins_blokada. Najczęściej jest pusty ale czasami faktycznie pojawia się blokada Cytat <obid>1272492<\/obid><obextra>0<\/obextra><obtype>151<\/obtype><workstation>SERWER<\/workstation><username>Szef<\/username><locktime>2023-11-20T19:25:07.037<\/locktime><counter>5<\/counter> Tylko odnoszę wrażenie że najpierw jest błąd bez wpisu, a później kilka takich z wpisem w blokadach. Czy coś tu robię źle? W przykładach w dokumentacji wygląda to podobnie ale nie wiem, może jakiś zasób źle zamykam albo coś w tym stylu? Link to postu
Dariusz Nowak 138 Napisano 21 Listopada 2023 Udostępnij Napisano 21 Listopada 2023 w Błąd 0x80040E31 przy dodawaniu kontrahenta Prosimy zapoznać się z rozdziałem FAQ zawartym w pomocy Sfery, szczególnie z poradą dotyczącą zwalniania obiektów: Zwalnianie nieużywanych obiektów w .NET Pytanie: W jaki sposób zwalniać nieużywane obiekty? Odpowiedź: Nieużywane obiekty w środowisku .NET należy zwalniać metodą: System.Runtime.InteropServices.Marshal.ReleaseComObject( obj ); Przy tworzeniu rozwiązań sferycznych należy zadbać o prawidłowe zwalnianie obiektów. Jeśli rozwiązanie dodaje kontrahentów/dokumenty w jakiejś pętli, to w każdym obiegu pętli. Warto też nie stosować "tasiemcowych konstrukcji" typu sgt.Kontrahenci — najlepiej każdy obiekt czy kolekcję osobno i jawnie zadeklarować, a po użyciu usunąć metodą ReleaseComObject. Link to postu
Daniel Kozłowski 1 171 Napisano 21 Listopada 2023 Udostępnij Napisano 21 Listopada 2023 w Błąd 0x80040E31 przy dodawaniu kontrahenta 1 godzinę temu, Anna Sałacińska napisał: I to działa ale czym dłużej działa serwer tym częściej mam błędy 0x80040E31 Istotne informacje, których brakuje: jaka jest konfiguracja sprzętowa (zwłaszcza ilość pamięci RAM) i programowa (edycja serwera SQL) tego serwera jakie są zasoby pamięci ram w momencie pojawiania się błędów po jakim czasie od rozpoczęcia operacji zapisu pojawia się błąd (szczegółowe logi rozwiązania) Link to postu
Anna Sałacińska 1 Napisano 11 Grudnia 2023 Autor Udostępnij Napisano 11 Grudnia 2023 w Błąd 0x80040E31 przy dodawaniu kontrahenta W dniu 21.11.2023 o 12:57, Daniel Kozłowski napisał: Istotne informacje, których brakuje: jaka jest konfiguracja sprzętowa (zwłaszcza ilość pamięci RAM) i programowa (edycja serwera SQL) tego serwera jakie są zasoby pamięci ram w momencie pojawiania się błędów po jakim czasie od rozpoczęcia operacji zapisu pojawia się błąd (szczegółowe logi rozwiązania) Xeon Gold 6248 (20c/40t). Pamięć to 128GB i dysk ssd raid10 (4dyksów ssd). Platforma Insert chodzi na Wirtualnej maszynie gdzie są przydzielone 32core i 60gb ram, SQL Runtime 2017 (14.0.2047.8), baza zajmuje ~30gb a miejsca wolnego jest około 100gb. Problem pojawia się trochę losowo, działa kilka godzin po czym zaczyna sypać błędami. Przykładowo, w sobotę było jakieś 4godziny dobrze, później były błędy jakieś dwie godziny z znowu chwilę działało. W niedzielę działało około dwie godziny i od tej pory non stop błędy. To znaczy wygląda to tak że dodaje jedno max dwa zamówienia ale zajmuje to 7-10sekund na każde i przy kolejnym wali błędem. Jak działa dobrze to zamówienie dodaje się dosłownie w 1-2sekundy. W dniu 21.11.2023 o 12:17, Dariusz Nowak napisał: Zwalnianie nieużywanych obiektów w .NET Pytanie: W jaki sposób zwalniać nieużywane obiekty? Odpowiedź: Nieużywane obiekty w środowisku .NET należy zwalniać metodą: System.Runtime.InteropServices.Marshal.ReleaseComObject( obj ); Trochę szkoda że nie jest to podane wprost w przykładach... Jest już dodane wszędzie, wydawało się że pomogło ale po jakichś dwóch godzinach znowu to samo. W dniu 21.11.2023 o 12:17, Dariusz Nowak napisał: Warto też nie stosować "tasiemcowych konstrukcji" typu sgt.Kontrahenci — najlepiej każdy obiekt czy kolekcję osobno i jawnie zadeklarować, a po użyciu usunąć metodą ReleaseComObject. są tworzone dosłownie tak jak jest to podane wyżej. Operacje jakie to dokładnie: - Otwarcie lub utworzenie kontrahenta - Uzupełnienie danych adresowych kontrahenta - zamknięcie kontrahenta - dodaje zk -- dodaje pozycje do zk - zamykam zk dodawanie pozycji wygląda tak foreach(p in produkty){ poz = zk.Pozycje.Dodaj(prodId); poz.CenaBruttoPrzedRabatem = p.brutto; poz.RabatProcent = p.rabat; poz.IloscJm = p.ilosc; System.Runtime.InteropServices.Marshal.ReleaseComObject(poz); } Link to postu
Dariusz Nowak 138 Napisano 12 Grudnia 2023 Udostępnij Napisano 12 Grudnia 2023 w Błąd 0x80040E31 przy dodawaniu kontrahenta 21 godzin temu, Anna Sałacińska napisał: dodawanie pozycji wygląda tak Radzimy jeszcze dokonać następujących modyfikacji w kodzie programu: zadeklarować osobną zmienną na kolekcję pozycji typu SuPozycje i korzystać z niej przez cały blok pętli foreach, a potem poza blokiem usunąć poprzez ReleaseComObject zamienić foreach na zwykłą pętlę Link to postu
Anna Sałacińska 1 Napisano 12 Grudnia 2023 Autor Udostępnij Napisano 12 Grudnia 2023 w Błąd 0x80040E31 przy dodawaniu kontrahenta suDodument.Pozycje jest tylko jako get, jak mam tam przekazać całą listę? I jak mam dodawać same pozycje? Bo w dokumentacji wszędzie jest że dodaje się je w taki sposób. Trochę nie rozumiem czemu mam zmieniać foreach na for - bo jak się domyślam to jest "zwykła" pętla. Przecież to jest pętla po danych które dostaje z mojego API, to nie coś co odczytuję ze sfery. Link to postu
Dariusz Nowak 138 Napisano 13 Grudnia 2023 Udostępnij Napisano 13 Grudnia 2023 w Błąd 0x80040E31 przy dodawaniu kontrahenta (edytowane) Proszę swój kod zorganizować zgodnie z poniższym przykładem. Zalecamy jawne deklarowanie wszystkich obiektów i kolekcji, unikanie "wielokrotnych przypisań" oraz wyeliminowanie wszystkich pętli foreach. //każdy obiekt i kolekcja są jawnie zadeklarowane InsERT.SuDokument oFS = null; InsERT.SuDokumentyManager oFSmngr = null; InsERT.SuPozycje oPozycje = null; //blok try-catch-finally gwarantuje wykonanie kodu odpowiedzialnego //za usuwanie obiektów nawet w przypadku wystąpienia błędów try { //tworząc obiekty unikamy "tasiemcowych przypisań" //i posługiwania się niejawnie utworzonymi obiektami oFSmngr = oSubGT.SuDokumentyManager; oFS = oFSmngr.WczytajDokument(40); oPozycje = oFS.Pozycje; oFS.Wyswietl(false); for (int i = 1; i <= oPozycje.Liczba; i++) { InsERT.SuPozycja oPoz = null; try { oPoz = oPozycje.Wczytaj(i); Debug.WriteLine((string)oPoz.TowarNazwa); } finally { if (oPoz != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(oPoz); } } } finally { if (oPozycje != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(oPozycje); if (oFS != null) { oFS.Zamknij(); System.Runtime.InteropServices.Marshal.ReleaseComObject(oFS); } if (oFSmngr != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(oFSmngr); } Edytowane 13 Grudnia 2023 przez Dariusz Nowak Link to postu
Anna Sałacińska 1 Napisano 14 Grudnia 2023 Autor Udostępnij Napisano 14 Grudnia 2023 w Błąd 0x80040E31 przy dodawaniu kontrahenta Zaczęłam przerabiać ale to nie zadziała. Ja nie edytuje dokumentu tylko dodaje nowe ZK. Więc nie mogę pobrać produktów z dokumentu i przejść po nich pętlą. Tylko ja napycham nowy pusty dokument pozycjami. I tak jak pisałam ten foreach nie przechodzi po danych ze sfery tylko po moich. I może to głupie pytanie, ale czy źle dodawane pozycje mogą spowodować błąd kontrahenta? Link to postu
Anna Sałacińska 1 Napisano 14 Grudnia 2023 Autor Udostępnij Napisano 14 Grudnia 2023 w Błąd 0x80040E31 przy dodawaniu kontrahenta Kod dodający kontrahenta wygląda dokładnie tak InsERT.Kontrahent kon = null; try { kon = this.sfera.sgt.Kontrahenci.Wczytaj(kid); kon.Miejscowosc = klient.miasto; kon.Ulica = klient.ulica; kon.NrDomu = klient.dom; kon.NrLokalu = klient.lokal; kon.KodPocztowy = klient.kod; try { if (kon.Telefony.Liczba == 0) { kon.Telefony.Dodaj(klient.telefon); } else { kon.Telefony[1].Numer = klient.telefon; } } catch (Exception e) { } kon.Email = klient.email; kon.NIP = klient.nip; if (klient.imie.Trim() != "") { kon.OsobaImie = klient.imie; } if (klient.nazwisko.Trim() != "") { kon.OsobaNazwisko = klient.nazwisko; } kon.AdresDostawy = true; kon.AdrDostKodPocztowy = klient.dowysylki_kod; kon.AdrDostMiejscowosc = klient.dowysylki_miasto; kon.AdrDostNrDomu = klient.dowysylki_dom; kon.AdrDostNrLokalu = klient.dowysylki_lokal; kon.AdrDostUlica = klient.dowysylki_ulica; string nazwa = ""; if (klient.firma != "") { kon.NazwaPelna = klient.firma; nazwa = klient.firma; } else { kon.NazwaPelna = klient.imie + " " + klient.nazwisko; nazwa = klient.imie + " " + klient.nazwisko; } kon.Nazwa = nazwa; kon.Zapisz(); } finally { if (kon != null) { kon.Zamknij(); System.Runtime.InteropServices.Marshal.ReleaseComObject(kon); } } Wywala się na kon.Zapisz(); I dopiero jak doda kontrahenta to przechodzi do dodawania zk. No ok zk, są dodawane w pętli ale i tak dodaje kontrahenta, a później zk. Więc mam rozumieć że błąd w dodawaniu pozycji spowoduje zablokowanie kontrahentów? Link to postu
Andrzej Kubik 1 098 Napisano 14 Grudnia 2023 Udostępnij Napisano 14 Grudnia 2023 w Błąd 0x80040E31 przy dodawaniu kontrahenta (edytowane) 3 godziny temu, Anna Sałacińska napisał: Kod dodający kontrahenta wygląda dokładnie tak Nie widzę tam dodawania kontrahenta jeśli w bazie brak kontrahenta o id = kid Wg helpa: Cytat Metoda Wczytaj Wywołanie metody spowoduje dodanie do kolekcji Kontrahenci nowego obiektu Kontrahent. Kontrahent dodawany tym sposobem do kolekcji musi istnieć wcześniej w bazie danych. Edytowane 14 Grudnia 2023 przez Andrzej Kubik Link to postu
Anna Sałacińska 1 Napisano 14 Grudnia 2023 Autor Udostępnij Napisano 14 Grudnia 2023 w Błąd 0x80040E31 przy dodawaniu kontrahenta Faktycznie mea culpa, tu jest edycja. W każdym razie można powiedzieć że wykonuję metodę dodającą lub edytującą kontrahenta - obiekt kontrahenta zostaje zamknięty. A dopiero później zaczynam dodawać zk, w którym kontrahenta poprzez jego id Czyli to jest dosłownie zk.KontrahentId = 123; A wywala się na zapisie kontrahenta. foreach(zamówienia){ kontrahentId = kontrahent.dodaj(...); zk = sgt.SuDokumentyManager.DodajZK(); zk.KontrahentId = kontrahentId; zk.Zamknij(); System.Runtime.InteropServices.Marshal.ReleaseComObject(zk); } to kontrahent.dodaj dodaje lub edytuje kontrahenta kon = sgt.Kontrahenci.Dodaj(); lub kon = sgt.Kontrahenci.Wczytaj(kid); kon.Miejscowosc = klient.miasto; kon.Ulica = klient.ulica; kon.Zapisz(); kon.Zamknij(); System.Runtime.InteropServices.Marshal.ReleaseComObject(kon); To do dodawania zk nawet nie dochodzi. Dlatego nie wiem czy dodawanie produktów w pierwszym zk, może popsuć zapis kontrahenta przy następnym. Link to postu
Dariusz Nowak 138 Napisano 28 Grudnia 2023 Udostępnij Napisano 28 Grudnia 2023 w Błąd 0x80040E31 przy dodawaniu kontrahenta W dniu 14.12.2023 o 15:18, Anna Sałacińska napisał: W każdym razie można powiedzieć że wykonuję metodę dodającą lub edytującą kontrahenta - obiekt kontrahenta zostaje zamknięty. A dopiero później zaczynam dodawać zk, w którym kontrahenta poprzez jego id Czyli to jest dosłownie zk.KontrahentId = 123; A wywala się na zapisie kontrahenta. Powyższy opis świadczy o tym, jakby zapis kontrahenta następował po tym, jak jest on wstawiany na ZK. Proszę się upewnić, że kolejność jest taka: operowanie na kontrahencie — zapis kontrahenta — wstawienie go na ZK. W dniu 14.12.2023 o 15:18, Anna Sałacińska napisał: foreach(zamówienia){ kontrahentId = kontrahent.dodaj(...); zk = sgt.SuDokumentyManager.DodajZK(); zk.KontrahentId = kontrahentId; zk.Zamknij(); System.Runtime.InteropServices.Marshal.ReleaseComObject(zk); } to kontrahent.dodaj dodaje lub edytuje kontrahenta Nazwa zmiennej wskazuje na typ całkowitoliczbowy, a kontrahent to typ obiektowy. W dniu 14.12.2023 o 15:18, Anna Sałacińska napisał: Dlatego nie wiem czy dodawanie produktów w pierwszym zk, może popsuć zapis kontrahenta przy następnym. Oczywiście, że tak nie powinno być. Należy szukać błędów w organizacji Pani kodu. Link to postu
Anna Sałacińska 1 Napisano 2 Stycznia Autor Udostępnij Napisano 2 Stycznia w Błąd 0x80040E31 przy dodawaniu kontrahenta Wstawiam większy fragment kodu może będzie łatwiej. Tu faktycznie może trochę w błąd wprowadzać to że moje klasy i klasy sfery mają te same nazwy. Te bez przestrzeni nazw InsERT są moje. Klasa kontrahentów: class Kontrahent { public int dodaj(Klient klient) { InsERT.Kontrahent kon = null; try { using (SqlCommand qis = new SqlCommand(@"SELECT isnull( CONVERT(int, (SELECT TOP 1[kh_Id] FROM[dbo].[kh__Kontrahent] JOIN[dbo].[adr__Ewid] on[adr_IdObiektu] =[kh_Id] and[adr_TypAdresu] = 1 WHERE adr_NIP = @nip AND adr_NIP != '' AND kh_Zablokowany = 0)) , isnull( CONVERT(int, (SELECT TOP 1 kh_Id FROM[dbo].kh__Kontrahent WHERE[kh_EMail] = @mail AND kh_Zablokowany = 0)) , 0)) ") ) { qis.Parameters.Add("@mail", SqlDbType.VarChar, 255).Value = klient.email; qis.Parameters.Add("@nip", SqlDbType.VarChar, 255).Value = klient.nip; kid = (int)qis.ExecuteScalar(); if (kid == 0) { kon = this.sfera.sgt.Kontrahenci.Dodaj(); kon.Typ = 0; kon.Miejscowosc = klient.miasto; kon.Ulica = klient.ulica; kon.NrDomu = klient.dom; kon.NrLokalu = klient.lokal; kon.KodPocztowy = klient.kod; kon.Telefony.Dodaj(klient.telefon); kon.Email = klient.email; kon.NIP = klient.nip; .... kon.Zapisz(); kid = kon.Identyfikator; } else { kon = this.sfera.sgt.Kontrahenci.Wczytaj(kid); kon.Miejscowosc = klient.miasto; kon.Ulica = klient.ulica; kon.NrDomu = klient.dom; kon.NrLokalu = klient.lokal; ... kon.Zapisz(); } } } catch (Exception ex) { .... } finally { if (kon != null) { kon.Zamknij(); System.Runtime.InteropServices.Marshal.ReleaseComObject(kon); } } return kid; } } Klasa zamówień: class Zamowienie { public int dodaj(Zamowienie zamowienie) { int dokumentId = 0; InsERT.SuDokument zk = null; try { Kontrahent kontrahent = new Kontrahent(); kontrahentId = kontrahent.dodaj(zamowienie.klient); if (kontrahentId == 0) { throw new Exception("Brak kontrahenta"); } zk = this.sfera.sgt.SuDokumentyManager.DodajZK(); zk.NumerOryginalny = zamowienie.id; zk.Podtytul = ""; zk.StatusDokumentu = 6; zk.KontrahentId = kontrahentId; foreach (Produkt produkt in zamowienie.produkty) { using (SqlCommand qProd = new SqlCommand(@"SELECT TOP 1 [tw_Id] FROM [tw__Towar] WHERE [tw_Symbol]= @ob_TowId")) { qProd.Parameters.Add("@ob_TowId", SqlDbType.VarChar, 20).Value = produkt.index; int prodId = 0; try { prodId = Convert.ToInt32(qProd.ExecuteScalar()); } catch (Exception) { } InsERT.SuPozycja poz = null; if (prodId > 0) { poz = zk.Pozycje.Dodaj(prodId); } else { poz = zk.Pozycje.DodajUslugeJednorazowa(); poz.UslJednNazwa = produkt.nazwa; } poz.CenaBruttoPrzedRabatem = produkt.brutto; poz.RabatProcent = produkt.rabat; poz.IloscJm = produkt.ilosc; System.Runtime.InteropServices.Marshal.ReleaseComObject(poz); } } zk.Zapisz(); dokumentId = zk.Identyfikator; zk.Zamknij(); System.Runtime.InteropServices.Marshal.ReleaseComObject(zk); } catch (Exception ex) { ... } finally { if (zk != null) { zk.Zamknij(); System.Runtime.InteropServices.Marshal.ReleaseComObject(zk); } } return dokumentId; } } Oraz dodawanie Subiekt.Zamowienie zamowinie = new Zamowienie(); foreach (Zamowienie zamowienie in lista) { zamowinie.dodaj(zamowienie); } Jak widać klasa Kontrahent dodaje lub otwiera do edycji InsERT.Kontrahent, zmienia dane, zapisuje i zamyka obiekt sfery. I dopiero jak doda kontrahenta to tworzy InsERT.SuDokument Ok, jest dokładniej InsERT.SuDokument zk = null; kontrahent.dodaj(zamowienie.klient);// tu moja klasa kontrahent która wywołuje sgt.Kontrahenci.Dodaj() lub sgt.Kontrahenci.Wczytaj() sgt.SuDokumentyManager.DodajZK(); no ale skoro zk na początku jest równe null to to nie powinno mieć żadnego wpływu. Przed wystąpieniu błędu w tabeli [dbo].[ins_blokada] albo nie ma wpisu albo jest z workstation podanym na stanowisko na którym jest uruchamiany ten program. Więc wychodzi na to że on blokuje sam siebie. Tego programu nie da się uruchomić kilka razy więc odpada opcja że niechcący został uruchomiony dwa razy i dwie instancje się na siebie nadkładają, próbując edytować tego samego kontrahenta. Link to postu
Anna Sałacińska 1 Napisano 16 Stycznia Autor Udostępnij Napisano 16 Stycznia w Błąd 0x80040E31 przy dodawaniu kontrahenta Baza subiekta została postawiona na nowo z wyczyszczoną bazą kontrahentów. Od tej pory działa prawidłowo. A z tego wnioskuję że sfera przestaje działać przy zbyt dużej ilości kontrahentów. Link to postu
Paweł B 20 Napisano 16 Stycznia Udostępnij Napisano 16 Stycznia w Błąd 0x80040E31 przy dodawaniu kontrahenta A ile kontrahentów miała Pani w bazie? Link to postu
Anna Sałacińska 1 Napisano 17 Stycznia Autor Udostępnij Napisano 17 Stycznia w Błąd 0x80040E31 przy dodawaniu kontrahenta Około 500-700 tysięcy, nie pamiętam dokładnie Link to postu
Paweł B 20 Napisano 17 Stycznia Udostępnij Napisano 17 Stycznia w Błąd 0x80040E31 przy dodawaniu kontrahenta Ja mam co prawda Navireo od kilku lat i u mnie już jest baaardzo blisko miliona ale nadal działa Link to postu
Polecane posty