[ASP.NET]Rollback niet mogelijk bij CREATE TABLE?

Pagina: 1
Acties:

  • Sensei_D
  • Registratie: Maart 2002
  • Laatst online: 23-04 10:34
Ik heb deze volgende functie van het internet af gehaald om met transactions te leren werken:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    Function MaakSP() As Integer
        Dim dbConnection As New SqlConnection(ConfigurationManager.GetSection("QCAppSettings")("QCconnString")) 'Wordt uit web.config gehaald
      
        dbConnection.Open()
        'Start the transaction    
        Dim myTrans As SqlTransaction = dbConnection.BeginTransaction()

        Try
            'Create the SqlCommand object, specifying the transaction through
            'the constructor (along with the SQL string and SqlConnection)
            'Alternatively, could set properties of myCommand
            'to specify the Connection, CommandText, and Transaction...
            Dim myCommand As New SqlCommand
            myCommand.Connection = dbConnection
            myCommand.Transaction = myTrans
  
            Dim sql1 As String = _
            "CREATE TABLE [GebruikersGroep] ([GebruikersgroepID] [int] IDENTITY (1, 1) NOT NULL)"
            Dim sql2 As String = _
            "INSERT INTO Test(test) VALUES('kan niet schrijven')"
            
            myCommand.CommandText = sql2
            myCommand.ExecuteNonQuery()
   
            'If we reach here, all command succeeded, so commit the transaction
            myTrans.Commit()
   
        Catch ex As Exception
            'Something went wrong, so rollback the transaction
            Response.Write(ex)
            myTrans.Rollback()
        Finally
            dbConnection.Close() 'Finally, close the connection
        End Try
    End Function
Deze gaat zoals hij hier staat goed. Zet ik echter achter CommandText sql1 neer; oftwel ik voer een create uit ipv een insert dat gaat het mis.
Ik krijg dan een fout: "Het ROLLBACK TRANSACTION-verzoek heeft geen corresponderende BEGIN TRANSACTION" Deze begin transaction is er echter wel degelijk zoals mag blijken.

Ik heb het nergens op internet kunnen vinden, ook niet op GoT; maar is het misschien niet mogelijk een rollback te doen op een create statement? Dat kan toch wel?

Owja, beide statements leveren (expres) een fout op...

[ Voor 5% gewijzigd door Sensei_D op 18-08-2005 11:07 . Reden: extra opmerking ]

sensei_d.fpv channel


  • Monkeybrains
  • Registratie: Juni 2001
  • Laatst online: 22:17
Bij databases is het zo dat er onderscheid gemaakt wordt tussen Data Manipulation en Data Definition statements. Data Manipulation (ergo insert, update,etc) kan je rollbacken, Data Definition (create table bijv) niet.

  • whoami
  • Registratie: December 2000
  • Laatst online: 02-05 14:39
Een create table kan zeker gerollbacked worden in SQL Server; probeer dit maar eens uit in Query Analyzer:
code:
1
2
3
begin tran
create table test ( a int )
rollback tran


Voer jouw code eens uit, terwijl je de SQL Profiler laat lopen, en kijk eens wat er allemaal naar sql server gestuurd wordt.

https://fgheysels.github.io/


  • Monkeybrains
  • Registratie: Juni 2001
  • Laatst online: 22:17
whoami schreef op donderdag 18 augustus 2005 @ 11:14:
Een create table kan zeker gerollbacked worden in SQL Server; probeer dit maar eens uit in Query Analyzer:
code:
1
2
3
begin tran
create table test ( a int )
rollback tran


Voer die code eens uit, terwijl je de SQL Profiler laat lopen, en kijk eens wat er allemaal naar sql server gestuurd wordt.
Ahh, daar hebben we dus een verschil tussen Oracle en SQL server. In Oracle kan het in ieder geval niet.

  • Sensei_D
  • Registratie: Maart 2002
  • Laatst online: 23-04 10:34
whoami schreef op donderdag 18 augustus 2005 @ 11:14:
Een create table kan zeker gerollbacked worden in SQL Server; probeer dit maar eens uit in Query Analyzer:
code:
1
2
3
begin tran
create table test ( a int )
rollback tran


Voer jouw code eens uit, terwijl je de SQL Profiler laat lopen, en kijk eens wat er allemaal naar sql server gestuurd wordt.
Ik ben helaas vergeten erbij te zeggen dat ik nu nog in een MSDE omgeving werk, dus ik kan nu de analyzer en de profiler niet gebruiken. Ik geloof je daarom maar op je woord, maar dan snap ik niet waarom dit in ASP.NET niet goed gaat terwijl dit met de analyzer wel kan :?

sensei_d.fpv channel


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 27-04 18:17

gorgi_19

Kruimeltjes zijn weer op :9

MariahCareyLover schreef op donderdag 18 augustus 2005 @ 11:47:
Ik ben helaas vergeten erbij te zeggen dat ik nu nog in een MSDE omgeving werk, dus ik kan nu de analyzer en de profiler niet gebruiken. Ik geloof je daarom maar op je woord, maar dan snap ik niet waarom dit in ASP.NET niet goed gaat terwijl dit met de analyzer wel kan :?
SQL Server 2k trial edition downloaden geen optie dan? :)

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • whoami
  • Registratie: December 2000
  • Laatst online: 02-05 14:39
Normaal gezien zou dat ook gewoon moeten werken.
Heb je je applicatie al eens gedebugged ?

Ik heb ff snel een testje gedaan, waar ik een create table rollback vanuit C#.NET, en dat lukt gewoon:
code:
1
2
3
4
5
6
7
8
9
10
11
12
conn.Open ();
            
SqlTransaction trans = conn.BeginTransaction();
            
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.Transaction = trans;
cmd.CommandText = "CREATE TABLE testje ( a INT )";
cmd.ExecuteNonQuery();

trans.Rollback();
conn.Close();

https://fgheysels.github.io/


  • Sensei_D
  • Registratie: Maart 2002
  • Laatst online: 23-04 10:34
whoami schreef op donderdag 18 augustus 2005 @ 12:09:
Normaal gezien zou dat ook gewoon moeten werken.
Heb je je applicatie al eens gedebugged ?

Ik heb ff snel een testje gedaan, waar ik een create table rollback vanuit C#.NET, en dat lukt gewoon:
code:
1
2
3
4
5
6
7
8
9
10
11
12
conn.Open ();
            
SqlTransaction trans = conn.BeginTransaction();
            
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.Transaction = trans;
cmd.CommandText = "CREATE TABLE testje ( a INT )";
cmd.ExecuteNonQuery();

trans.Rollback();
conn.Close();
Jezus je bent snel ;)
Ik wilde dus net een soortgelijke code posten waarin ik dus ipv een commit een rollback deed en dat werkt weer wel. Pas als de query echt misgaat en er een exception ontstaat dan lukt de rollback niet. Hij doet dan ook geen create dus ik denk dat er in dat geval weinig te rollbacken valt :+ Daar zal ie wel op mislopen denk ik....

[Edit]
Het lijkt er dus op dat de rollback om de een of andere reden dus niet wil werken in het catch block als er gebruik wordt gemaakt van een create statement, in alle andere gevallen werkt het wel :?
Opgesomt:
- Als er gebruik wordt gemaakt van een insert statement in het try block, werkt rollback in het catchblock wel
- Als er gebruik wordt gemaakt van een create statement en er wordt een rollback gedaan in het try block dan werkt dit wel
- Als er gebruik wordt gemaakt van een create statement en er wordt een rollback gedaan in het catchblock dan werkt het niet

Ikzelf vind dit enigzins raar, iemand die opheldering kan geven misschien?

[ Voor 27% gewijzigd door Sensei_D op 18-08-2005 13:13 ]

sensei_d.fpv channel


  • whoami
  • Registratie: December 2000
  • Laatst online: 02-05 14:39
MariahCareyLover schreef op donderdag 18 augustus 2005 @ 12:58:
[...]


edit:

Het lijkt er dus op dat de rollback om de een of andere reden dus niet wil werken in het catch block als er gebruik wordt gemaakt van een create statement, in alle andere gevallen werkt het wel :?

Dat zou me wel erg stug lijken. Of die rollback nu in een catch wordt uitgevoerd, of niet, zou niet mogen uitmaken.
Ook dit voorbeeldje werkt:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SqlTransaction trans = conn.BeginTransaction();
try
{
   SqlCommand cmd = new SqlCommand();
   cmd.Connection = conn;
   cmd.Transaction = trans;
   cmd.CommandText = "CREATE TABLE testje ( a INT )";
   cmd.ExecuteNonQuery();
   throw new Exception();                
}
catch( Exception ex )
{
  trans.Rollback();
}
finally
{
      conn.Close();
}
Opgesomt:
- Als er gebruik wordt gemaakt van een insert statement in het try block, werkt rollback in het catchblock wel
- Als er gebruik wordt gemaakt van een create statement en er wordt een rollback gedaan in het try block dan werkt dit wel
- Als er gebruik wordt gemaakt van een create statement en er wordt een rollback gedaan in het catchblock dan werkt het niet

Ikzelf vind dit enigzins raar, iemand die opheldering kan geven misschien?
Zoals ik al eerder zei: debug de code eens.
Zet een breakpoint in je code, en voer deze dan stap per stap uit. Ga eens na welke regel een exception veroorzaakt, en je naar je catch doet springen.
Het kan bv zijn dat je transactie bv toch al gecommit werd, en je nadien pas een exceptie krijgt ?
Kijk ook eens mbhv de profiler wat er precies naar sql server gestuurd wordt.

[ Voor 13% gewijzigd door whoami op 18-08-2005 14:04 ]

https://fgheysels.github.io/


  • Sensei_D
  • Registratie: Maart 2002
  • Laatst online: 23-04 10:34
En die werkt ook als de tabel al bestaat?
Het enige verschil wat ik zie is die throw exception, wat is dat precies als ik vragen mag?

[Edit]
Mja debuggen heb ik al een paar keer gedaan, hij springt op het juiste moment naar de exception(voor de commit en op de regel waarop een statement wordt uitgevoerd die misgaat)
Daar loopt de debugger vast op de regel myTrans.Rollback() met de eerder genoemde foutmelding :(

[ Voor 52% gewijzigd door Sensei_D op 18-08-2005 14:12 ]

sensei_d.fpv channel


  • whoami
  • Registratie: December 2000
  • Laatst online: 02-05 14:39
MariahCareyLover schreef op donderdag 18 augustus 2005 @ 14:09:
En die werkt ook als de tabel al bestaat?
Het enige verschil wat ik zie is die throw exception, wat is dat precies als ik vragen mag?
throw exception gooit een exceptie, zodanig dat er naar de catch gesprongen wordt.
Hetzelfde wat er eigenlijk gebeurt moest die table gewoon al bestaan.

Ik heb m'n code eens veranderd:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 SqlTransaction trans = conn.BeginTransaction();
try
{
      SqlCommand cmd = new SqlCommand();
      cmd.Connection = conn;
      cmd.Transaction = trans;
      cmd.CommandText = "CREATE TABLE testje ( a INT )";
      cmd.ExecuteNonQuery();
      trans.Commit();
}
catch( Exception ex )
{              
    trans.Rollback();
    MessageBox.Show (ex.Message);
}
finally
{
     conn.Close();
}


Als ik nu de eerste keer die code uitvoer, gaat alles goed.
Als ik de code de 2de keer uitvoer, krijg ik 'There's already an object name 'testje' in the database'.

Heb jij wel zeker een transactie gestart ?

[ Voor 46% gewijzigd door whoami op 18-08-2005 14:28 ]

https://fgheysels.github.io/


  • Sensei_D
  • Registratie: Maart 2002
  • Laatst online: 23-04 10:34
Whoami, als ik jouw code zo omzet naar asp.net dan krijg ik de 2de keer die fijne melding die ik eerder noemde weer, kwor gek :+

Nu heb ik er dit van gemaakt:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
        dbConnection.Open()
        Dim myTrans As SqlTransaction = dbConnection.BeginTransaction()
        Try
            Dim myCommand As New SqlCommand
            myCommand.Connection = dbConnection
            myCommand.Transaction = myTrans
  
            Dim sql1 As String = _
            "CREATE TABLE [test] ([a] [int])"

            Dim sql2 As String = _
            "UPDATE Test SET me=you"
 
            myCommand.CommandText = sql1
            myCommand.ExecuteNonQuery()
            myCommand.CommandText = sql2
            myCommand.ExecuteNonQuery()

            myTrans.Commit()
   
        Catch ex As Exception
            Response.Write(ex)
            myTrans.Rollback()
        Finally
            dbConnection.Close() 'Finally, close the connection
        End Try

De tabel bestaat nog niet, dus de eerste execute gaat goed
Daarna gaat de 2de execute mis
We komen in de exception terecht en nu werkt de rollback :?

Dus als een statement misgaat NA mijn create statement dan is er niks aan de hand. Is het echter alleen de create statement die misgaat dan gaat de rollback op zun bek, pffff

Het weer werkt ook niet erg mee zeg :+

sensei_d.fpv channel


  • whoami
  • Registratie: December 2000
  • Laatst online: 02-05 14:39
MariahCareyLover schreef op donderdag 18 augustus 2005 @ 15:12:
Whoami, als ik jouw code zo omzet naar asp.net
Eh, die code kan je niet omzetten naar asp.net; ASP.NET is geen taal, maar een platform.
Je kan hooguit die code draaien binnen een asp.net omgeving.
/miereneuk-modus.

https://fgheysels.github.io/


  • Sensei_D
  • Registratie: Maart 2002
  • Laatst online: 23-04 10:34
whoami schreef op donderdag 18 augustus 2005 @ 15:14:
[...]

Eh, die code kan je niet omzetten naar asp.net; ASP.NET is geen taal, maar een platform.
Je kan hooguit die code draaien binnen een asp.net omgeving.
/miereneuk-modus.
Mwaaaa je hebt gelijk :D
Ik dacht VB.NET, maar typte het verkeerd in :+

Misschien moet ik het maar gewoon even laten liggen, ik staar me wel vaker blind op problemen, kijk morgen wel weer ofsow..

sensei_d.fpv channel


  • Sensei_D
  • Registratie: Maart 2002
  • Laatst online: 23-04 10:34
Nou m.b.v. de msdn site van microsoft kwam ik er wel uit.
De catch wordt als volgt om het probleem met de create statements te omzeilen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
        Catch e As Exception
            Try
                myTrans.Rollback()
            Catch ex As SqlException
                If Not myTrans.Connection Is Nothing Then
                    Response.Write("An exception of type " & ex.GetType().ToString() & _
                                      " was encountered while attempting to roll back the transaction.<br>")
                End If
            End Try
            Response.Write("An exception of type " & e.GetType().ToString() & e.Message.ToString & _
                            "<br>was encountered while inserting the data.<br>")
            Response.Write("Neither record was written to database.")
Als ik dit goed lees krijgt men nu een extra fout als de rollback mislukt doordat de connectie naar de database is verbroken. Mislukt de rollback om een andere reden dan laat men het zo, wat dus gebeurt bij het proberen te rollbacken van een create statement.

Misschien niet extreem netjes, maar voor mij wel werkbaar, in alle andere statements gaat dit immers goed dus ik mag er toch wel vanuit gaan dat de 2de catch alleen optreed bij connectieverbreking of dus bij een create statement...

sensei_d.fpv channel


  • whoami
  • Registratie: December 2000
  • Laatst online: 02-05 14:39
Euh, als ik van jou was, zou ik toch echt m'n rollback in de catch zetten hoor.

Doe het dan zo:

code:
1
2
3
4
5
6
7
8
9
10
try
{
}
catch( Exception ex )
{
   if( myTrans != null && myTrans.Connection != null )
   {
       myTrans.Rollback();
   }
}


Oh, ok, dat doe je dus. Maar dan nog, vind ik die code niet netjes. Ik zou het met een if doen. :P

https://fgheysels.github.io/

Pagina: 1