webForumDet fria alternativet

transactioner och öppna stänga connection

Databaser & SQL

8 svar · 444 visningar · startad av Prästen

Medlem sedan dec. 2000537 inlägg
Frågan#1

Om jag vill öppna och stänga databas efter varje fråga.

command.Connection.Open();
command.Text="INSERT INTO produkter (namn) VALUES ('dator')";
command.ExecuteNonQuery(); //skicka frågan till databasen
command.Connection.Close();

command.Connection.Open();
command.CommandText="INSERT INTO produkter (prodID) VALUES (1)";
command.ExecuteNonQuery(); //skicka frågan till databasen
command.Connection.Close();

Kan jag då om jag vill lägga till transaktioner göra såhär?.

command.Connection.Open();
command.Text="BEGIN TRANSACTION";
command.ExecuteNonQuery(); //skicka frågan till databasen
command.Connection.Close();

command.Connection.Open();
command.Text="INSERT INTO produkter (namn) VALUES ('dator')";
command.ExecuteNonQuery(); //skicka frågan till databasen
command.Connection.Close();

command.Connection.Open();
command.CommandText="INSERT INTO produkter (prodID) VALUES (1)";
command.ExecuteNonQuery(); //skicka frågan till databasen
command.Connection.Close();

command.Connection.Open();
command.Text="COMMIT TRANSACTION";
command.ExecuteNonQuery(); //skicka frågan till databasen
command.Connection.Close();

Eller måste jag göra allt detta i en och samma fråga?

Medlem sedan dec. 200012 464 inlägg
#2

Kan jag då om jag vill lägga till transaktioner göra såhär?.

Nej.

Eller måste jag göra allt detta i en och samma fråga?

Du måste starta och avsluta transaktionen inom samma uppkoppling.

Medlem sedan dec. 2000537 inlägg
#3

Men det är ju säkrare att öppna och stänga connection efter varje fråga, finns det nåt annat sätt att göra transaktioner även om man vill öppna och stänga efter varje fråga?

http://www.webforum.nu/showthread.php?s=&postid=778857#post778857

Medlem sedan dec. 200012 464 inlägg
#4

I den tråd du länkade till så skulle jag byta ordet fråga mot transaktion.

Beroende på dbms så går det att skicka flera frågor i ett anop

sql = "begin start transaction; insert into x values(1);
insert into y values(2);commit;end";

eller så kan man använda en procedure om det stöds.

Medlem sedan dec. 2000537 inlägg
#5

Men det finns ju fall där man behöver få ut @@IDENTITY ju, och då kan man ju inte skicka in alla frågor på en gång ju. hur gör man då?.

Medlem sedan dec. 200012 464 inlägg
#6

Om det handlar om SQL server så går det med

sql = "set nocount on insert into t values(...) select @@identity"

eller med en stored procedure (rekommenderas).

Medlem sedan maj 20012 812 inlägg
#7

Om man använder Transactioner så har man redan från början gjort avkall på prestandan.

Precis som lars säger så måste alla transactioner ske med samma koppling. Det finns en väg runt detta och det är att blanda in COM+ men det är knappast någon bättre lösning rent prestanda mässigt.

Frågan är dock om din kod verkligen måste skrivas in i en transaktion. Det är faktiskt inte så jätte-vanligt. För oftas när man gör INSERT/DELETE/UPDATE så gör man det oftast en operation, eller flera som dock inte är beroende avvarandra.

- M

Medlem sedan dec. 2000537 inlägg
#8

Jo i det här fallet måste vi göra det.

Ska lägga in lite saker i olika tabeller, och måste ha rätt ID nummer från de andra tabellerna så det matchar och så. Därför får det aldrig bli fel, så att bara 1 tabell blir uppdaterad men inte de andra.

Men spelar det så stor roll att inte stänga och öppna efter varje fråga?, är det OK att inte göra det. För annars är det lugnt ju.

Såhär tex. Detta är bara ett exempel för att illustrera, inget som jag använder. men känns mycket skönt att .NET hade färdiga Transactions objekt :h , slipper man gnola själv

SqlCommand sqlcommand=new SqlCommand();
sqlcommand.Connection=new SqlConnection("Server=burken\\mindatabas;Database=test;User ID=sa;Password=spya;Trusted_Connection=False");
sqlcommand.Connection.Open();

try
{
   sqlcommand.Transaction=sqlcommand.Connection.BeginTransaction();

   sqlcommand.CommandText="INSERT INTO produkter (namn) VALUES ('mutti')";
   sqlcommand.ExecuteNonQuery();

   sqlcommand.CommandText="SELECT @@IDENTITY AS ID";
   int ID=int.Parse(sqlcommand.ExecuteScalar().ToString());

   sqlcommand.CommandText="INSERT INTO produktID (prodID,namn) VALUES (" + ID + ",'mutti')";
   sqlcommand.ExecuteNonQuery();

   sqlcommand.Transaction.Commit();
}
catch(Exception shit)
{
   sqlcommand.Transaction.Rollback();
   Response.Write(shit.Message);
}

sqlcommand.Connection.Close();
Medlem sedan maj 20012 812 inlägg
#9

Så hade jag gjort, det är rätt jobbigt att ha med transaktioner att göra om du måste stänga mellan varje fråga.

Anledningen till att jag sa att man skall ha sin koppling öppen så kort tid som möjligt i det inlägg som du refererar till, innebär inte att du måste stänga din koppling efter varje fråga om det krävs att den är upp.

Du skall ha din koppling öppen så kort tid som MÖJLIGT. Vilket i fallet med transaktioner blir framtills transaktionen är klar. Däremot så finns det ingen anlednig att ha en databaskoppling öppen om den inte behöver vara öppen, men just med transaktioner så behöver den det :)

Så fort sätt du som du har skrivit ikoden ovan.

- Magnus

262 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2
119 ms — deklarationer (db)
0 ms — hämta statistik (cache)
134 ms — hämta tråd, inlägg och bilagor (db)
125 ms — ändringar (db)