Search

onze sponsors

microsoft_logo.gif


 

computrain_logo.JPG

Forum Login | Register
   Forum

 

Subject: Geen foutmelding, dus geen rollback
Prev Next
You are not authorized to post a reply.

Author Messages
Ellen HeijmansUser is Offline

Posts:101

23-03-2009 15:38:36 Alert 
Ik heb een raar probleem met SQL-code die al een jaar goed werkt en die nu opeens bij verschillende klanten problemen gaat geven. Het probleem kan ik zelf niet reproduceren.

Wat is het geval? Het gaat om uren die via de site ingevoerd worden en in een bepaalde tabel worden gezet. Daarna kan een manager op een ander deel van de site die uren fiatteren waarna ze doorgeboekt worden naar een andere tabel (voor verdere verwerking in een ander programma). Vervolgens worden de uren uit de eerste tabel verwijderd. Het geheel vindt plaats binnen een transactie en een try...catch constructie.

Nu opeens begint het steeds vaker voor te komen dat blijkbaar de uren niet gekopieerd zijn naar de doeltabel, daar geen foutmelding op wordt gegenereerd, daardoor de code gewoon doorloopt, en de records vervolgens in de brontabel worden gewist. Resultaat: gegevens weg.

Wat kan de reden zijn dat de INSERT niet goed gaat? Maar, interessanter nog, waarom komt daar geen foutmelding van? Dit kan m.i. niets met locks te maken hebben, daar SQL Server dat zelf goed afhandeld door gewoon te wachten tot de page weer wordt vrijgegeven (dit zou misschien kunnen gebeuren als iemand zijn uren zit in te voeren terwijl tegelijkertijd uren gewist worden). Bovendien zou een INSERT toch helemaal geen last moeten hebben van locks.

Op dit moment staat op de webserver SQL Express en inmiddels werken daar aardig wat klanten op, dus kan die het misschien niet meer aan? Blijft nog steeds de vraag waarom daar geen foutmelding van komt.

Wie kan mij op weg helpen?
Eduard BeijnesUser is Offline

Posts:37

24-03-2009 12:10:29 Alert 

ondanks je info helpt het als je de betreffende code post.

verder worden niet alle fouten door try catch afgehandeld.

enkele regelens uit bol sql2005:

A TRY CATCH construct catches all execution errors with severity greater than 10 that do not terminate the database connection.

Errors that terminate the database connection, usually with severity from 20 through 25, are not handled by the CATCH block because execution is aborted
when the connection terminates.

Errors with severity of 20 or higher that terminate the SQL Server Database Engine task processing for the session. If an error occurs with severity of 20 or higher and the database connection is not disrupted, TRY…CATCH will handle the error.

Attentions, such as client-interrupt requests or broken client connections.

When the session is terminated by a system administrator using the KILL statement.

The following types of errors are not handled by a CATCH block when they occur at the same level of execution as the TRY…CATCH construct:

Compile errors, such as syntax errors, that prevent a batch from executing.

Errors that occur during statement-level recompilation, such as object name resolution errors that happen after compilation due to deferred name resolution.

These errors are returned to the level that ran the batch, stored procedure, or trigger.

dus je foutmeldingsvraag, met name het gebrek hieraan, zou kunnen komen door hierboven vermelde oorzaken. hiernaast  als er in je catch een error zit zit daar weer geen error handler op (tenzij je nested try catch gebruikt).

een voorbeeld wat ik gezien heb is: applicatie werkt altijd goed en opeens geeft het problemen. wat bleek: de applicatiehad heeft een timeoutwaarde waarbinnen het normaal gesproken afgehandeld was door sql server. vervolgens wordt de db groter en kwam het af en toe voorbij deze grens en ging het fout. de timeout werdt niet afgehandeld ... soms werkte het wel en soms niet en steeds vaker niet ... misschien iets wat in jouw situatie ook optreed.

hopelijk kun je er wat mee.


 


An ape in an suit stays an ape.
Eduard BeijnesUser is Offline

Posts:37

24-03-2009 15:34:43 Alert 
/* een voorbeeldje wat niet in de catch komt */
use master
begin try
/* sys.dm_os_wait_stats is correcte tabelnaam */
select * from sys.dm_os_wait_statsx
end try
begin catch
print 'kom ik hier wel of niet'
end catch
print 'einde'

An ape in an suit stays an ape.
Ellen HeijmansUser is Offline

Posts:101

25-03-2009 17:27:26 Alert 

Hoi Eduard,

Hierbij een deel van de code waar het om gaat. Het kan niet om een fout gaan die de databaseverbinding verbreekt. Het probleem is namelijk dat de INSERT niets insert en geen fout geeft. Als het om bijv. een error > 20 zou gaan, dan zou de DELETE die er na komt niet uitgevoerd worden. En dat is nou juist het probleem, er wordt niets toegevoegd, maar wel gewist.

BEGIN TRY
   BEGIN TRAN

   SET
DATEFIRST 1

   --Het wegschrijven van de uren in de PlanRadtabel
   INSERT INTO dbo.dwwuren (Personeelsnummer, Projectnummer, Datum, Soort, Uren, Opmerking, ESS_Gewijzigd)
   SELECT Personeelsnummer, Projectnummer, Datum, Soort, Uren, Opmerking, 1 FROM dbo.ESS_dwwuren
   WHERE Personeelsnummer = @Personeelsnummer
      AND (dbo.fn_WeeknummerISO(Datum) = @Week AND YEAR(dbo.fn_BepaalEinddatumWeek(Datum)) = @Jaar)

   --Het wissen van de uren uit de brontabel
   DELETE
FROM dbo.ESS_dwwuren
   WHERE Personeelsnummer = @Personeelsnummer
      AND (dbo.fn_WeeknummerISO(Datum) = @Week AND YEAR(dbo.fn_BepaalEinddatumWeek(Datum)) = @Jaar)

   --De oude status wordt vervangen door de nieuwe
   UPDATE dbo.ESS_Weekstatus
   SET Status = 3
   WHERE Personeelsnummer = @Personeelsnummer
      
AND WeekJaar = dbo.fn_VersleutelWeekJaar(@Week, @Jaar)
      AND Status =
      AND Soort = @Soort

   COMMIT TRAN

END TRY

BEGIN CATCH

   ROLLBACK TRAN

   --Wegschrijven van de foutmelding

   DECLARE @Foutmelding nvarchar(4000), @Foutnummer as int, @FoutErnst as int

   SET @Foutnummer = ERROR_NUMBER()
   SET @Foutmelding = ERROR_MESSAGE()
   SET @FoutErnst = ERROR_SEVERITY()

   INSERT INTO dbo.Logboek (Tijd, Personeelsnummer, [Week], Jaar, Melding)
      VALUES (GETDATE(), @Personeelsnummer, @Week, @Jaar, 'Fout ' + CAST(@Foutnummer as nvarchar(400)) + ': ' + @Foutmelding)

   RAISERROR(@Foutmelding, @FoutErnst, 1)

END CATCH

END

André KammanUser is Offline
PASS Nederland

Posts:137


26-03-2009 10:14:13 Alert 
Hoi Ellen,

Heb je misschien triggers op dwwuren ?

Groeten,

André
Ellen HeijmansUser is Offline

Posts:101

27-03-2009 13:33:05 Alert 
Nee, geen triggers. Alleen een PK. En er komt wel een foutmelding met een rollback bij een PK-constraint error. Bovendien zou het ook in geval van een trigger in alle gevallen fout moeten gaan of bij geen. Toch?
André KammanUser is Offline
PASS Nederland

Posts:137


31-03-2009 16:48:50 Alert 
Is me wel eens overkomen dat een Instead of trigger vrolijke iets heel anders ging doen dan de bedoeling was, vandaar...

Kan het zijn dat je niets insert omdat je in bepaalde gevallen niets heb ?
En dat het dus alleen maar lijkt alsof hij wel delete...
(Je zou de rowcount kunnen loggen.. Of er even triggers op te zetten om het insert / update / delete verkeer te loggen)
Eduard BeijnesUser is Offline

Posts:37

02-04-2009 12:06:07 Alert 

Over:
[quote]Nu opeens begint het steeds vaker voor te komen dat blijkbaar de uren niet gekopieerd zijn naar de doeltabel, daar geen foutmelding op wordt gegenereerd, daardoor de code gewoon doorloopt, en de records vervolgens in de brontabel worden gewist. Resultaat: gegevens weg.[/quote]

en vervolgens kijk ik naar de where clauses:

   WHERE Personeelsnummer = @Personeelsnummer
      AND (dbo.fn_WeeknummerISO(Datum) = @Week AND YEAR(dbo.fn_BepaalEinddatumWeek(Datum)) = @Jaar)

   WHERE Personeelsnummer = @Personeelsnummer
      AND WeekJaar = dbo.fn_VersleutelWeekJaar(@Week, @Jaar)
      AND Status = 2
      AND Soort = @Soort

je gebruikt 2 verschilllende where clauses met een functie erin (aanname). ik heb zo het vermoeden dat daarin je gedrag verschil zit. bijv dat bij de where voor 1 en 2 iets false (cq geen resultaten) geeft en je where (3) met delete een true (wel resultaten). en dat dus vrolijk de delete wel wordt uitgevoerd en je andere actie niet.

in de oorzaken sfeer: misschien dat je in je 1e functie code hebt zitten welke gevoelig is voor grotere tabellen en dat het daarom "opeens" problemen geeft. gezien de naam zou dat vreemd zijn overigens aangezien het als een berekenfunctie uitziet.

ik meen gelezen te hebben (even geen tijd voor check) dat je try catch op je "boven" code van toepassing is en niet op je subcode. dus als er wat fout gaat in je functie is het de vraag of de catch erboven (de body die de functie aanroept) er wel wat van merkt. Of dit klopt is voor jou (aangezien je de code hebt ) wat makkelijker te checken. Misschien dat je op functie nivo een try catch toe kunt voegen aan je functies of meer errorchecking op de ouderwetse manier ... of "print"jtes etc.


 


An ape in an suit stays an ape.
Eduard BeijnesUser is Offline

Posts:37

02-04-2009 12:08:31 Alert 

nog een aanvuling:

als de wheres zich verschillend gedragen qua true/false dan verklaart het ook waarom try/catch niets geeft aangezien het misschien voor sql server geheel correcte code is die door sql server correct wordt uitgevoerd ... of het datgene is wat je wilt of niet.

 


An ape in an suit stays an ape.
Peter ter BraakeUser is Offline

Posts:4

02-04-2009 14:05:51 Alert 

Wellicht dat je eens de connection settings van de verschillende klanten moet bekijken. Ik heb ooit iets vergelijkbaars gehad doordat sommige klanten met de ANSI_NULLS optie in hun connectiestring andere resultaten kregen.

Peter

You are not authorized to post a reply.
Forums > Forums > Ontwikkelen > Geen foutmelding, dus geen rollback



ActiveForums 3.6
  
Copyright (c) 2012 PASS Nederland   Privacy Statement  Terms Of Use