Treg VBus?

Oslo, 21. september 2025

Endret 22. og 28. september 2025

Tidvis får jeg henvendelser fra kunder om at de synes Visma Business (VBus) har blitt treg. Det skjer gjerne etter en oppgradering. For å sitere en av Vismas høye herrer (eller i alle fall med høy hatt) – fritt gjengitt etter erindringen: Hver versjon, som har ny funksjonalitet, vil nettopp av den grunn være mer ressurs-krevende enn sin forgjenger. Det er normalt ikke slik at det oppleves, men det kan kanskje måles. For de som «hopper over» mange versjoner og oppgraderer f.eks. fra 15 direkte til 19, vil ytelsesforskjellene kunne være større, men det er ikke gitt at det er merkbart. Noen opplever altså at det går tregere.

Det kan være andre årsaker til at VBus blir tregere over tid, som ikke har noe med versjon å gjøre:

-      Flere samtidige brukere, større transaksjonsvolum

-      Større transaksjonstabeller, fortrinnsvis slike som er gjenstand for endringer – slike som ordrelinjer og produkttransaksjoner

-      Større trafikk på saldo-tabeller som ofte endres; varepartier, lagersaldo og kundesaldo

-      Endringer i den tekniske infrastrukturen; fysiske eller virtuelle servere og SQL-server (som gjerne skjer i forbindelse med oppgradering av VBus eller bytte av ASP-leverandør) eller svakheter i selve nettverket

-      Nye eller endrede integrasjoner med andre applikasjoner

-      Større trafikk på andre applikasjoner, som trekker på de samme ressursene som VBus bruker

Det kan også være noe i VBus som er annerledes i den siste versjonen enn forrige. Jeg synes disse henvendelsene er de vanskeligste å gå løs på, for det er sjelden én enkelt årsak, og aldri enkle årsaker. Dette er det jeg pleier å se på:

Logger

I VBus er det flere logger. Den første som jeg ser på, er Bedriftsdatafeil (og for så vidt Systemdatafeil). Påfallende ofte er det loggført melding som:

-      Mistet forbindelse under utførelse av SQL-kommando …

-      Database connection lost. Re-connect is tried

-      TCP Provider: Tidsavbruddsperioden for semaforen har utløpt. Communication link failure.

-      Named Pipes Provider: Det oppstod en uventet nettverksfeil. Communication link failure.

-      Unspecified error occurred on SQL Server. Connection may have been terminated by the server.

-      TCP Provider: Nettverkstilkoblingen ble avbrutt på det lokale systemet.

-      TCP Provider: Et tilkoblingsforsøk mislyktes fordi den tilkoblede parten ikke svarte på riktig måte etter en tidsperiode, eller den etablerte tilkoblingen mislyktes fordi den tilkoblede verten ikke …

-      TCP Provider: Det angitte nettverks­navnet er ikke lenger tilgjengelig.

Felles for disse situasjonene er at det har oppstått et brudd i forbindelsen mellom VBus og SQL-server. Hvorfor bruddet har oppstått er det vanskelig å si noe om, men siden VBus umiddelbart etterpå klarte å skrive feilmeldingen i tabellen, er det åpenbart at bruddet mellom VBus og SQL-server var kortvarig. Feilen ligger altså (i prinsippet) hverken i VBus eller på SQL-server, men i kommunikasjonen mellom dem. Dette er en sak for nettverksfolkene og de som har ansvar for det tekniske miljøet. Her må man se om ressursene er rett dimensjonert. I et VM-miljø kan det være aktuelt å sette opp dedikert minne og CPU både for SQL-server og terminalserver. Det er naturlig å tenke på at årsaken til bruddet er timeout. Altså at SQL-server ikke svarer raskt nok eller at svaret ikke formidles raskt nok slik at VBus (eller Windows) «oppfatter» at kommunikasjonen er brutt. Da er det også naturlig å tenke at det mange ganger tar «lang» tid, uten at det ender opp med timeout – og at når dette skjer hos mange brukere samtidig, så oppleves det som tregt.

En annen feil jeg ser i Bedriftsdatafeil hos enkelte er SQL-kommando nr … gav duplisert primærnøkkel. Hvis det vises til SQL-kommando nr 2547, har dette skjedd i ordrelagringsprosedyren. Ellers er det grunn til å mistenke en trigger. Feilen forteller at prosedyren eller triggeren forsøker å sette inn en rad i en tabell med en primærnøkkel som allerede finnes. Her er det bare å kaste seg over spesialløsningene og se etter instruksjonen INSERT INTO. Typisk er det slik at rett før INSERT INTO finnes en SELECT max(PK)+1 FROM … (hvor PK er primær­nøkkel i tabellen) slik at raden som settes inn har neste ledige nr. Her kan man bli lurt om dette ikke ligger i en TRANSACTION. VBus er ikke helt stueren på dette punktet. Jeg har sett at om to brukere samtidig gjør noe som gjør at VBus skal opprette en ny ordre­journal (og fortrinnsvis én til hver av dem) så kan begge forsøke å opprette journal med samme nr. Den første lykkes, den andre mislykkes, men går videre – og dermed bruker begge samme journal. Den første som oppretter produkttransaksjoner, lykkes med det, mens den andre lykkes, utrolig nok med å overskrive dem. Dette har jeg bare sett i et transaksjons­tungt miljø, men der manglet det etter hvert noen millioner transer. I versjon 18 ble det tatt et skritt på veien til en bedre håndtering av dette; tabellene Aktiv sesjon, Tidligere sesjon, Aktiv systemprosess og Aktiv bedriftsprosess er satt opp med primærnøkkel som IDENTITY-kolonne. Dette kan med fordel også gjøres med tabeller som Ordrejournal, Realisasjonsjournal og Oppdatering. Vi får se når versjon 20 dukker opp. Enn så lenge tenker jeg at det ikke skjer noe med dette i versjon 20 heller. Se for øvrig avsnittet Triggere.

Det hender at jeg kommer over at SQL-kommando nr … forårsaket deadlock. Brukeren det gjelder (dvs. den ene av dem) har da fått en melding i VBus på nynorsk som kan se slik ut: Transaction was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. Deadlock betyr at en bruker har låst en tabell og forsøker å lese en annen, mens en annen har låst den tabellen og forsøker å lese tabellen som den første har låst. De blokkerer altså for hverandre. SQL-server oppdager dette, og peker ut den ene av de to som må gi seg – som blir offeret for å løse blokkeringen. Det tar ikke lang tid før SQL-server oppdager deadlock; dette er en innstilling på SQL-server som kan endres. Og det er ikke bare tabeller som låses på SQL-server, det er mange ressurser som kan være involvert i en deadlock. Igjen vil det være naturlig å tenke at årsaken er en trigger eller en prosedyre som isolert sett er grei nok, men som ikke spiller godt sammen med VBus eller de andre triggerne og/eller prosedyrene. Snakk med den brukeren som fikk meldingen om deadlock og spør hva som ble gjort når situasjonen oppstod. Husk at det også var en annen bruker involvert, uten at det er loggført hvem dette var og hva vedkommende gjorde. Kanskje var det en prosedyre som gikk i bakgrunnen. Det beste er om vi klarer å reprodusere situasjonen; da kan den meldes til Visma om den fremdeles oppstår når alle triggere er disablet og ingen prosedyrer går.

Det kan være mange andre feilmeldinger i Bedriftsdatafeil som bør følges opp, som jeg ikke gir eksempler på her – fordi de ikke har noe med treghet å gjøre, men gjerne er en feil i en trigger eller i ordrelagringsprosedyren.

Uten at det strengt tatt har med treghet å gjøre, anbefaler jeg at IT-ansvarlig jevnlig sjekker Aktiv sesjon og logger ut de som åpenbart har glemt å gjøre dette. Og når jeg er innom det som bør kontrolleres jevnlig; sjekk samtidig tabellen EDI-feilmelding.

For lenge siden kom det en mulighet til å loggføre endringer i tabeller. Skoleeksempelet var endring av bankkonto-nummer til leverandører i Aktør-tabellen, rett før remittering – og reversering rett etterpå. For godt over 40 år siden jobbet jeg i Fellesdata som var spare­bankenes datasentral. Ansvarlig for utenlands­systemet skulle slutte, og flytte til Sveits. Siste dag i den måneden han sluttet, falt på en søndag – og da sikkerhets­ansvarlig mandagen etter, oppdaget at han ikke bare hadde vært på kontoret den helgen, men også logget seg inn i systemene, gikk alarmen. Han hadde ikke gjort noe galt, bare ryddet etter seg og oppdatert systemdokumentasjonen. Nok om det. Mange har satt opp logging et stort antall kolonner på tabeller som helt naturlig endres løpende, med det resultat at Bedriftsendringslogg blir svært stor. Nå er det slik at SQL-server ikke bruker mye tid på å legge en ny rad inn «bakerst» i en tabell med få kolonner. Litt blir det, og det er alltid gunstig å tenke gjennom om man faktisk har behov for detalj-informasjon om endringer som skjedde for mange år siden. Det er oppfordring både til å være kritisk til hva som loggføres og til å sette opp en jobb som jevnlig sletter gamle rader uten interesse.

Noen har laget spesialløsninger for utvidet logging. Jeg har laget noen selv. Igjen er det viktig å være kritisk og tenke hvilken nytte virksomheten har av det som blir logget.

Ut over det som loggføres i VBus, har både Windows og SQL-server egne logger. Her er det mye som logges, som ikke krever noen tiltak. Loggene kan filtreres, slik at det er lettere å se om noe er vondt og leit. Det er viktig at det blir gjort med jevne mellomrom. For godt over 20 år siden jobbet jeg i Coop Elektro. En dag fikk vi behov for backup av en database og ble rimelig lang i maska da IT-ansvarlig fortalte at det ikke var noen backup der, til tross for at backup-programmet hadde gått hver natt i mange år. Lenger ned i loggene var det loggført at backup ikke var tatt og årsaken til det. Den loggen hadde ingen lest.

Sanering

Jeg har skrevet om standard sanering og radikal sanering tidligere, så jeg skriver ikke noe mer om det her. Hensikten med sanering er å sørge for at de tabellene som det er mye trafikk på, altså som oppdateres ofte, ikke er større enn nødvendig. I tillegg til sanering av produkt­transaksjoner, kan det være effektivt å slette ferdigbehandlede (realiserte) ordrelinjer med endelig kostpris som er bokført. Når en lagerhåndtert ordrelinje slettes i VBus, slettes også tilhørende reservasjonsrader. Strengt tatt trenger ingen ordrelinjene etter at de er ferdigbehandlet, siden vi finner historikken i produkttransaksjon (eller Alle produkt­transaksjoner om noen er sanert). For å kunne slette realiserte ordrelinjer, må det fra og med versjon 17 åpnes for dette i adgangs­kontrollen. Jeg skrev om versjon 17 da den kom for tre år siden, men det jeg ikke skrev, er at det også må åpnes for å slette plukkede/ferdigmeldte ordrelinjer. Personlig synes jeg dette er litt klønete; det hadde vært fint om man kunne slette ferdigbehandlede ordrelinjer, uten samtidig å åpne for å slette plukkede/ferdigmeldte ordrelinjer som ikke er realisert og ferdigbehandlet. Slik er nå VBus, og det kommer ikke til å bli endret bare fordi jeg har meninger om det.

Når du er i gang med sletting av gamle ferdigbehandlede ordrelinjer, bruk anledningen til også å slette gamle tilbud som ikke ble til salg. Her kan du antagelig like gjerne slette selve ordren også; ordrelinjene blir slettet når ordren slettes. Hvis du skulle ha behov for å se på et gammelt tilbud, så har du det i dokumentarkivet.

Store tabeller hvor neste rad legges «bakerst» i tabellen skaper mindre treghet i VBus enn store tabeller som med hyppige endringer. De største tabellene som endres ofte er vanligvis ordrelinje, reservasjon og produkttransaksjon. Tabellene med hyppigst endringer er lagersaldo, kundesaldo, vareparti, beholdningsendring, hovedbokssaldo (uten og med ansvarsenhet) og Bilagsserie (selv om den er liten). Hovedbokssaldo-tabellene endres nesten bare i forbindelse med bilagsoppdatering, men denne er til gjengjeld treg i VBus – på grunn av låsing. Her kom det i versjon 18.10 en mulighet for utsatt saldo-oppdatering, som kan være et tiltak for de med mange og/eller store bunter. Legg merke til at kundesaldo oppdateres ikke bare i forbindelse med bilagsoppdatering, men også når det gjøres en endring på en salgsordre som endrer Ordresaldo tilvekst (kr). Det er hver gang Fakt. beløp i fremt. (kr) på ordren endres. Kundesaldo-tabellen kan gjøres mindre ved å slå sammen kunder, f.eks. opprette en kunde som heter «Gamle kunder» og bytte kundenr på kunder uten bevegelse siste 5-6 år.

Jeg skulle ønske det var mulig å gjøre noe liknende med produkter uten bevegelse f.eks. siste 5-6 år. Det er det ikke innenfor standard VBus. Hos enkelte har vi vært litt rampete og «sanert» gamle produkter ved å sette unntas lagerhåndtering på alle ordrelinjene og produkt­transaksjonene til de som skal «saneres», slette de tilhørende reservasjonene og lagersaldoene. Det må selvfølgelig kontrolleres at det ikke finnes vare­partier, beholdnings­endringer eller transaksjoner som ikke er ferdig­behandlet på de produktene som skal «saneres». Jeg har sett hos noen kunder at konsulenter med svak impulskontroll og utilfredsstillende systemforståelse har vært rampete før meg. Skal man gjennomføre slik «rydding» i gamle data, må det gjøres på en måte som gjør at det ikke ramler gamle lik (eller det som er igjen av dem) ut fra skap senere. Hos en kunde jeg var hos nylig, så vi at det i 2015 var slettet varepartier og lagersaldo for en rekke utgåtte produkter, uten å gjøre noe med de underliggende transaksjonene. Det var noen produkter som ikke var utgått allikevel, slik at lagersaldo ble gjenopprettet. Da de lagersaldoene ble regenerert, ramlet det inn gamle varepartier over en lav sko. 

Indekser

Når VBus leser fra tabeller, går det raskest når det kan gjøres oppslag i det som kan likne på et stikkord-register i en bok. Dette kalles indeks på tabeller i databasen. Alle tabeller har en indeks på det som er primærnøkkelen i tabellen, enten den består av én, to eller flere kolonner (det er vel ingen tabeller i VBus som har flere enn tre kolonner i primærnøkkelen). Primærnøkkelen i Vareparti-tabellen er Produknr, Lagernr og Partinr. Primærnøkkelen i Ordrelinje-tabellen er Ordrenr, Linjenr. Når vi har primærnøkkelen, kan vi gå rett på sak. Ofte, f.eks. ved regenerering av lagersaldo, må vi lete frem ordreliner som gjelder et bestemt Produktnr og Lagernr. Derfor har Ordrelinje-tabellen en sekundær-indeks med bl.a. Produktnr og Lagernr som indeks-kolonner. VBus bruker denne når det skal søkes etter ordrelinjer med et bestemt Produktnr (og evt. Lagernr). Alle tabeller har i tillegg til primær-indeksen, en låse-indeks med Prosessnr og Redigeringsstatus som indeks-kolonner. Noen tabeller har en sorterings-indeks hvor Sort.sekv.nr er en av indeks-kolonnene. Fra og med versjon 19.10 har alle tabeller en EndretTidsstempel-indeks. Jeg er usikker på om nytten er større enn kostnaden. En del tabeller har (som Ordrelinje-tabellen) sekundær-indekser ut over de to som alle har (og sorterings-indeksen som noe har). På produkttransaksjon er det fem, siden denne tabellen brukes i flere prosesser i VBus og til rapportering på kryss og tvers.

Det er mulig å sette opp egne indekser i VBus. De som har allokerte ordre, kan med fordel sette opp en indeks på ordrelinje-tabellen med Allokert ordrenr og Allokert ordrelinjenr som indeks-kolonner. Det kan gjøre at VBus jobber raskere med allokerte ordre.

Det er også muligheter for å sette opp indekser med SQL Mgmt Studio. Det sirkulerer mange skript som analyserer statistikken (på SQL-server) og foreslår nye indekser. Dette må håndteres med nennsomhet. Jeg ser jevnlig databaser som er massivt overindeksert. For selv om indekser ofte vil gjøre søkingen raskere, så er kostnaden at oppdatering (innsetting av nye rader og endring av indekserte kolonner) tar lenger tid. Det finnes også skript som analyserer statistikken og viser ventetid knyttet til oppdatering av indeksene. For når en kolonne endrer verdi på en rad, må alle indekser som viser til denne oppdateres. SQL-server gjør dette imponerende effektivt, det må sies. Men det må gjøres. Det tar (om enn bitte lite) tid. Hver gang. Indekser som settes opp med Mgmt Studio, kan settes opp med INCLUDED COLUMNS (eller løvet som det også kalles). Det kan være nyttig, men siden VBus stort sett henter alle kolonnene når tabeller leses, så kan det godt skje at kostnaden er større enn nytten. Det er vel derfor det ikke er mulig å bruke dette når indekser settes opp i VBus. Så er det en annen problemstilling som er viktig. Hvis en standard-tabell som har DME-kolonner, ved oppgradering til ny versjon av VBus, får nye standard-kolonner – skal disse plasseres foran DME-kolonnene. Det oppgraderingsprogrammet gjør er å gi tabellen et nytt navn, opprette tabellen på nytt med kolonnene i riktig rekkefølge, kopiere radene fra den gamle tabellen, legge inn standard indekser og de som tidligere er opprettet i VBus, men ikke de som er opprettet direkte i databasen. Disse går tapt i prosessen (for så vidt sammen med triggere på samme tabell). Om du lurer på hvor ofte det skjer at det kommer nye kolonner på eksisterende tabeller, så kan ingen si noe om fremtiden, men du kan sjekke modellendringer fra versjon 8 og fremover. I versjon 19.10 kommer det to nye kolonner i alle tabeller. Så moralen er nå som før; skript ut alle indekser og triggere før oppgradering. Om du ikke er hellig overbevist om at du trenger indekser med kolonner i løvet, så opprett dem fra VBus, ikke med Mgmt Studio.

Indekser bør regenereres med jevne mellomrom. Med Mgmt Studio kan det settes opp jobber som regenererer indekser som har blitt fragmenterte. Vi anbefaler at dette gjøres på databaser når de blir store (som er et relativt begrep). Det kan også kjøres analyser som viser hvor fragmentert en indeks er. Det kan settes opp free space (angitt med fill-factor) på indekser, men som standard er indeksene i VBus-databasene uten free space. Jeg har sett noen eksempler på at alle indekser er satt opp med free space. Det er uklokt. Man bør unngå free space på clustrede indekser. Dette er indekser på primærnøkkelen i tabeller hvor neste rad normalt legges «bakerst» i tabellen. På saldo-tabellene kan free space på indeksen til primærnøkkelen ha noe for seg (disse er ikke clustret).

Det er mulig å regenerere indekser fra VBus, men det bør ikke gjøres når andre brukere er pålogget. VBus sletter alle indeksene og bygger de opp på nytt. Om en standard-indeks eller en indeks som er opprettet i VBus, av en eller annen grunn skulle være slettet, så vil den bli opprettet – noe som ikke skjer om man har en jobb på SQL-server som regenererer indekser. VBus regenererer bare indekser som er «kjent» for VBus, ikke de som er opprettet direkte på SQL-server. Litt synd er det at man ikke kan sette opp en tidsstyrt oppgave i VBus for å regenerere indekser. Synd er det også (for ikke å si rart) at det ikke er mulig å bruke dette menyvalget på firma som låner tabeller fra andre (altså har felles tabeller).

Triggere, ordrelagringsprosedyren og VBS-jobber

Triggere brukes når vi vil at en bestemt endring i en tabell skal føre til at noe skjer som VBus ikke gjør. Det kan være en integrasjon med en annen applikasjon, hvor det er viktig at den andre applikasjonen oppdateres med det samme. For eksempel en adresseforandring på en kunde eller leverandør, en ny kontakt­person, etc. Triggeren fanger opp en endring (INSERT, UPDATE eller DELETE) på en tabell, evt. hvilke(n) kolonne(r) som har fått ny(e) verdi(er) hvis det er UPDATE, leser det triggeren er programmert til å lese og gjøre det den skal. Her er det mulig å trå realt feil – for alle kolonner i alle tabeller er åpne for endringer, selv om de ikke er det i VBus. Så det kan skapes inkonsistens og triggeren kan gi en utilsiktet belastning. I tillegg til feil av typen duplisert primærnøkkel, som nevnt tidligere.

Ordrelagringsprosedyren (som egentlig heter Lagring av ordre pros.) er en SQL-prosedyre som kalles av VBus hver gang en ordre lagres, det godkjennes utskrift av et ordredokument eller et menyvalg på ordre eller ordrelinje utføres. For allokerte ordre vil lagring av én enkelt ordre i VBus, kunne føre til at et stort antall allokerte ordre også oppdateres – og ordrelagringsprosedyren kalles for hver enkelt av dem. Hver gang en trigger eller en prosedyre leser en tabell, låses hele tabellen inntil de radene som skal hentes er funnet. Det er derfor indekser er så nyttig; de reduserer lesetiden vesentlig. Man kan bruke WITH(NOLOCK) for å unngå låsing ved en SELECT, men ikke ved en UPDATE. Det er viktig å sikre at lesing av store tabeller skjer slik at SQL-server har en indeks å støtte seg til og ikke gjennomføre UPDATE om det ikke er nødvendig.

Det samme gjelder VBS-jobber. Dette er «fremmede» programmer som «snakker» med VBus via en tjeneste (VBS) og ber VBS om å lese data og oppdatere data (innenfor rammen av det VBus tillater). Mange VBS-programmer er skrevet slik at både lesing og skriving skjer direkte i databasen, og da har vi de samme bekymringer som med triggere og ordrelagringsprosedyren.

Ved oppgradering av VBus til ny versjon er det alltid viktig å sjekke om noen av spesialløsningene som er laget, kan erstattes av ny funksjonalitet. Jeg skrev en gang en trigger på tabellen Lagersaldo som sjekket om det var regenerering av lagersaldo som ble utført. I tilfelle ble Endret av bruker endret til Regen. av og så brukernavnet til den som regenererte lagersaldoen. Dermed kunne vinduet som brukes til regenerering av lagersaldo holde de rader utenfor som ikke er endret siden siste regenerering. I versjon 16.10 kom kolonnen Regenerert dato i lagersaldo-tabellen. Da kan triggeren fjernes og vinduet justeres til å støtte seg på ny funksjonalitet.

Da jeg jobbet i Amesto laget en kollega av meg en BIG-komponent som loggførte hvilke vinduer som ble åpnet, av hvilken bruker, i hvilket firma og når. Jeg satte opp en DME-utvidelse slik at man kunne se loggen i VBus og skrev en DELETE trigger på tabellen Aktiv bedriftsprosess, slik at vi også fikk logget når brukeren lukket vinduet. Men VBus endret bruken av tabellen Aktiv bedriftsprosess i versjon 18, slik at det ikke ble satt inn en rad i denne tabellen når vinduet ble åpnet. Fra og med versjon 18 blir det først opprettet en rad i tabellen om brukeren legger til, endrer eller sletter noe i vinduet som han eller hun bruker. Da klarer ikke triggeren å fange opp når brukeren lukker vinduet. Så om du er Amesto-kunde hvor VBus er oppgradert til eller forbi versjon 18, har en DME-utvidelse som viser vindusbruk og fremdeles har en trigger med navnet LogEndPrc på tabellen ActPrc, så kan du høre med Amesto om den ikke bør slettes. Eller kan jeg gjøre det for deg.

Det er ikke ofte at en trigger må endres i forbindelse med en oppgradering av VBus, men det hender. Kontroll av dette er viktig.

Helt uavhengig av VBus-oppgradering: Jeg har deprimerende ofte sett triggere som hører til en integrasjon med annen applikasjon, som bedriften sluttet å bruke for flere år siden. Dette er gjerne triggere som oppdaterer en postkasse (gjerne med navnet Outbox) med endringer som den andre applikasjonen skulle ta tak i. Postkassa vokser og vokser fordi det ikke er noen som henter meldingene. Sukk hjerte, men brist ikke.

Noen konsulenter med lang og dyp SQL-kompetanse anbefaler at ordrelagringsprosedyren innledes med SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED for å redusere blokkering. Personlig er jeg litt i tvil. For meg ser det ut som om VBus bruker READ COMMITTED under selve ordreregistreringen, men endrer til REPEATABLE READ under lagring (dog ikke ved bruk av Lagre om) – og tilbake til READ COMMITTED etterpå. Siden ordrelagringsprosedyren kjøres i en TRANSACTION (etter at VBus har gjort sitt), vil REPEATABLE READ blokkere for at andre brukere endrer ordre og ordrelinjer mens lagringen pågår. Jeg er usikker på hvor klokt det er å tukle med dette; VBus har, så langt jeg kan se, ikke endret hvordan ISOLATION LEVEL brukes ved lagring av ordre på de siste versjonene. Det fungerer i alle fall likt i 19.10 som i versjon 15. Men det ser ut som at det kom inn en endring i versjon 18.10 eller 19.00 på andre områder i VBus enn lagring av ordre. Tidligere vekslet VBus mellom READ COMMITTED og READ UNCOMMITTED, men i versjon 19 er det (så langt jeg kan se) bare READ COMMITTED. Det gir mer blokkering enn før, men om dette er årsaken til mer deadlock i versjon 19, vet jeg ikke. Merk at det ikke bare under lagring av ordre VBus bruker REPEATABLE READ. Hver gang det gjøres noe med en ordre (dog ikke Lagre om) som endrer den, bruker VBus REPEATABLE READ, ved generering av innkjøps/produksjonsordre, ved godkjenning av ordredokumenter (bestilling, tilbud, ordrebekreftelser, plukklister, pakksedler, faktura, etc.) og ferdigmelding.

Innstillinger i VBus

Det er ikke mange innstillinger i VBus som direkte kan påvirke ytelse, men i Ordrebehandling har vil alternativet: Oppbevar varepartier. Personlig synes jeg ikke hjelpeteksten er helt spot-on når det gjelder hvorfor man bør velge det ene eller det andre. Jeg mener å erindre en anbefaling fra Visma om å oppbevare varepartier av hensyn til sporing, men «prisen» blir at Vareparti-tabellen blir stor. Jeg tenker at man får best ytelse om man ikke velger Oppbevar varepartier.

I Felles behandling i Bedriftsopplysninger kan du velge Tillat asynkron databasetilgang. Det samme kan velges i Systemoppl.behandl. i Systemopplysningene om det skal gjelde alle bedrifter. Personlig har jeg ingen erfaring med dette, men i hjelpeteksten står det: I noen av Visma Business sine databasespørringer er det tillatt med asynkron databasespørring, som betyr at flere uavhengige spørringer kan behandles samtidig mot databasen. Hvilke spørringer dette gjelder, vet jeg ikke, men Copilot skriver at Asynkron databasetilgang på SQL Server betyr at en klientapplikasjon kan sende en forespørsel til databasen og fortsette å kjøre annen kode mens den venter på svar, i stedet for å blokkere og vente til databasen er ferdig med å behandle forespørselen. Dette gir bedre ressurs­utnyttelse og kan forbedre ytelsen, spesielt i applikasjoner med mange samtidige brukere eller langvarige spørringer. Jeg er redd for at dette er et parameter som ikke lenger har noen effekt. Det er ikke støtte for asynkron databasetilgang i Sp_ExecuteSql som fra og med versjon 19 brukes av VBus til å få utført oppgaver på SQL-server.

Vinduer

Det er mulig å sette opp et vindu i VBus slik at det tar tid å åpne. Jeg har sett vindu for ordreregistrering hvor utvalget er alle salgsordre med Posisjonering ved åpning; siste rad. Da tar det lenger og lenger tid å åpne vinduet etter hvert som ordretabellen vokser. Dette skaper ikke treghet i VBus i andre anledninger enn ved åpning av dette vinduet. Vinduer som henter mye informasjon fra andre tabeller og bruker dette i utvalg og/eller sortering, vil ofte være tregere å åpne enn om utvalg og eventuell sortening baserer seg på tabellen som åpnes. Hvis mange av vinduene som er mye i bruk har ukloke oppsett, vil VBus oppleves som tregere med årene siden tabellene blir større. Det kan være mer effektivt å se på vinduene med nye øyne, enn å krympe tabellene.

SQL-logg og trace

Tabellen Bedriftsdatafeil (og for så vidt Systemdatafeil) viser loggførte SQL-feil, men viser ikke alt som skjer. Hvis det er en bestemt prosess, f.eks. fakturering, som alltid går tregt, kan man foreta dette mens SQL-logg er på. Dette er et menyvalg i VBus som gjør at alle SQL-kommandoene (eller instruksjonene om du vil) blir loggført i en tekst-fil, med dato og klokkeslett ned på millisekund, sammen med hvor lang tid hver kommando tok. Da kan man se om det er noen enkelt-kommandoer som er urimelig tidkrevende. Vel så nyttig er det å se på tiden mellom hver SQL-kommando og trekke fra tiden som selve SQL-kommandoen tok. Da får vi den tiden som VBus brukte i tillegg til (altså uavhengig av) SQL-server. Det var lettere å lese SQL-loggen før versjon 19. Da brukte VBus EXEC for å utføre SQL-kommandoene. Fra og med versjon 19 bruker VBus Sp_ExecuteSql, som gjør det litt vanskeligere å lese, men gir i prinsippet bedre ytelse. Det kan tenkes at utviklingsavdelingen er litt i tvil her, for i versjon 19.10.2 som bare er i beta for forhandlere, er det en mulighet til å gå tilbake til bruk av EXEC (i stedet for Sp_ExecuteSql) – for å kunne sammenlikne de to metodene.

SQL-logg i VBus favner bare det som den brukeren gjør som har satt SQL-logg på. Det må slås av for å se txt-filen. På SQL-server finnes det muligheter for å følge alt som skjer på SQL-server. Et bedre alternativ er å bruke det verktøyet som Visma har laget: Gui trace listener. Her er det mulig å sette opp filtre slik at det er mulig å finne blomsten (eller tistlene om du vil) i skogen av hendelser. Det kan sorteres slik at de tyngste aktivitetene kommer opp øverst. Tidkrevende aktiviteter blir merket med rødt. Verktøyet krever ikke noe tradisjonell installasjon, det må bare kopieres inn – og bruker registry for å finne VBus. Jeg tenker dette er et verktøy som kunne ha blitt brukt mer, men det er ingen løsning i seg selv. Det er heller ikke slik at det er fort gjort å finne ut hva som er vondt og leit. Det kan kanskje fortelle noe om hvor flaskehalsene er. Dette er ikke et brukerverktøy; det er for litt garvede VBus-konsulenter med inngående system- og SQL-forståelse. 

Andre applikasjoner

Jeg har vært innom triggere som forer andre applikasjoner med informasjon fra VBus. Omvendt; når andre applikasjoner skal oppdatere VBus, skjer det gjerne via VBS eller som en EDI-melding. Noen velger å skrive direkte til databasen. Hos en kunde jeg jobbet mye med, så vi at Aktør-tabellen ble oppdatert helt urimelig ofte, uten at noen kunne forstå hvorfor. Der satte jeg opp en logg som viste en rad for hver gang tabellen ble oppdatert, med tidspunkt, SQL-bruker, applikasjonsnavn og maskin (server) som foretok oppdateringen og kom frem til synderen. Dette hadde gått raskere om ikke alle applikasjoner hadde brukt samme SQL-bruker. Jeg anbefaler at det settes opp egen SQL-bruker for hver applikasjon; at ikke alle bruker SA.

Rapporteringsverktøy vil ofte ha behov for å lese store deler av transaksjonstabellene og koble til felt fra tabeller som aktør, produkt, hovedbokskonto og liknende. Dette kan skape det som kalles en HEADBLOCK på SQL-server, noe som brukere av VBus kan oppleve som at VBus «henger» en stund før det løsner. Ikke alle som lager rapporteringsløsninger har like god forståelse for hva det gjør med driften. En løsning som kan være å hente data om natten til en separat rapporteringsdatabase, men da er det ikke RealTime-rapportering lenger. Så får man avveie ulike interesser mot hverandre.

Replikering av database

Noen har valgt å bruke en teknikk på SQL-server som er slik at det som skjer i en database samtidig oppdaterer en annen database. Dette kalles replikering og den replikerte databasen brukes gjerne til rapportering. Dermed har man RealTime-rapportering og tanken er at komplekse og ressurskrevende lesinger ikke skal belaste driften. Replikering kan settes opp på forskjellige måter, men de som kan mye om dette forteller av selve replikeringen i seg selv kan være en belastning. Man bør se på hvilke tabeller og kolonner som man trenger i den replikerte databasen og utelate alt man ikke trenger fra replikeringen.

 

Resten av min blogg kan du lese her: frode.antun/VBus/blogg

 

frode@antun.no