webForumDet fria alternativet

Rollback problem

6 svar · 352 visningar · startad av erka

erkaMedlem sedan dec. 19994 597 inlägg
#1

Hej
Vad är det jag inte greppat om rollback och transaktioner. Jag ska köra två inserts, om någon av dem failar, rollbacka hela transaktionen.

För att testa om den fungerade bytte jag namn på tabellen som den andra inserten ska använda, får felmeddelandet Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = 1, current count = 0. Och den rollbackar inte den första inserten, utan den läggs till även om den andra failar

Vad jag vill åstakomma är alltså
Två inserts i en transaiktion, där båda insertsen inte får genomslag i databasen om någon av dem misslyckas. Ska det vara så svårt :)

alter procedure createInternalCourse

@coursecode varchar(10),
@name varchar(30),
@teacherInChargeAdress varchar(50),
@teacherInChargeName varchar(30),
@teacherTutorsAdress varchar(50),
@teacherTutorsName varchar(30),
@courseOmbud int,
@coursePoints int,
@hoursTutored int = 0

as

declare
@err int

BEGIN TRANSACTION

--Skapa den i Course
insert into Course (coursecode,course_name,fk_in_charge_teacher_address,fk_in_charge_teacher_name,fk_tutors_teacher_address,fk_tutors_teacher_name,fk_courseombud_student_id,tutored_hours) values (@coursecode,@name,@teacherInChargeAdress,@teacherInChargeName,@teacherTutorsAdress,@teacherTutorsName,@courseOmbud,@hoursTutored)
SELECT @err = @@error
IF @err <> 0 
	BEGIN 		
		ROLLBACK TRANSACTION 
		RETURN @err 
	END

--Om första gick bra
ELSE
	--Skapa den i internal, har medvetet bytt namn på Internalcourse till Internalcourse  för generera fel
	insert into Internalcourse (fk_course_coursecode,points) values (@coursecode,@coursePoints)
	SELECT @err = @@error
	IF @err <> 0 
		BEGIN 		
			ROLLBACK TRANSACTION 
			RETURN @err 
		
		END
	ELSE
		BEGIN
			COMMIT TRANSACTION
		END
NöffMedlem sedan nov. 2003569 inlägg
#2

Om det är SQL-server testa detta...

SET XACT_ABORT ON
BEGIN TRANSACTION

insert into Course (coursecode,course_name,fk_in_charge_teacher_address,fk_in_charge_teacher_name,fk_tutors_teacher_address,fk_tutors_teacher_name,fk_courseombud_student_id,tutored_hours) values (@coursecode,@name,@teacherInChargeAdress,@teacherInChargeName,@teacherTutorsAdress,@teacherTutorsName,@courseOmbud,@hoursTutored)

insert into Internalcourse (fk_course_coursecode,points) values (@coursecode,@coursePoints)

COMMIT TRANSACTION

erkaMedlem sedan dec. 19994 597 inlägg
#3

Tack men @@error blir ju nytt efter varje writekommando, denna har ju ingen rollback heller, så varför skulle den fungera, Vad menas med XACT_ABORT ON

Red
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_set-set_0rqs.asp

Måste ju gå att lösa på ett enklare sett, men klassisk if rollback etc. Ska ju inte vara problem, eller har jag missuppfattat något.

Red2.
Nej det fungerar fortfarande inte :( Det i första inserten rollbackas inte om det går fel i andra.

erkaMedlem sedan dec. 19994 597 inlägg
#4

Det gäller ju bara runtime error, tänk om en tabellen i insert nr2 saknas, det är inte ett runtimeerror verkar det som.

erkaMedlem sedan dec. 19994 597 inlägg
#5

Nu börjar jag snart slita mitt hår. Gör jag med nöffs exempel ett RAISEERROR mellan de två insertsen fungerar rollbacken, byter jag namn på tabellen inblandad i insert nummer två gör den inte rollback. Borde det inte också räknas som runtimeerror?

tohaMedlem sedan dec. 1999698 inlägg
#6

Har följt tråden och kollat lite på problemet. Den var lite jobbig får jag säga. Jag har iaf lagt märke till att om du kör en GO efter INSERT:en, innan du kollar @@error så verkar den inte hänga sig och hålla table lock. Dvs det verkar fungera; vet inte riktigt varför men... :OO

SET XACT_ABORT ON
BEGIN TRAN

insert into book (titel, namn) values ('1', '1')
insert into book2 (titel, namn) values ('2', '2')  -- tabell 'book2' finns ej.
[b]GO[/b]

DECLARE @err int
SET @err = @@error
IF @err <> 0 
BEGIN
	PRINT 'return @@error = ' + convert(varchar, @err)
	ROLLBACK TRAN
	RETURN
END

PRINT 'Allt väl'
COMMIT TRAN
RETURN
erkaMedlem sedan dec. 19994 597 inlägg
#7

toha,tack för du också tar dig lite tid,men här har du ju problemet att @@error skrivs på nytt efter varje write, din kod skulle inte fungera om det gick fel i den första inserten, om inte book hade funnits alltså.

Någon som kan ge klarhet i
1. Varför det inte orsakar ett runtime error om en tabell inte finns och en insert försöker sätta in värden i den

2. Vad spelar det för roll om jag använder GO, GO betyder väll att han ska tolka det som en batch, men det gör han väll automatiskt iom. det är en transaktion

122 ms totalt · 3 externa anrop · cache AV · v20260731051352-full.56cc9887
0 ms — hämta statistik (cache)
0 ms — hämta forumlista (cache)
120 ms — hämta tråd, inlägg och bilagor (db)