Toon posts:

Transaction IsolationLevel lezen niet toestaan Asp.net

Pagina: 1
Acties:
  • 101 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Hallo,

Ik heb een volgende vraag.
Ik heb een databank (access) waarvan ik gegevens inlees, en wegschrijf. Als ik nu een nieuwe record wil toevoegen lees ik eerst het hoogste nummer uit. Dit sla ik op en waardeer ik op met 1 en schrijf de nieuwe record weg.

Hiervoor heb ik een transaction aangemaakt die als alles gelukt is een commit afgeeft.

Nu wil ik deze transactie graag volledig op slot zetten. Want ik wil voorkomen dat 2 gebruikers hetzelfde nummer uitlezen en dit opwaarderen.


Dus eigenlijk read and write lock, maar is dit wel mogelijk ?

Want ik heb gezocht na de locking op transactions en het hoogste level zou Serializable
(Volatile data can be read but not modified, and no new data can be added during the transaction. )
zijn. maar dan kun je data nog lezen.

Is er een oplossing voor dit probleem ? Ik gebruik asp.net c#

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Je moet het gewoon niet op deze manier doen. Je kunt beter een autonummer veld gebruiken en die waarde uitlezen. In [rml][ Delphi] autoincrement van laatste INSERT-query opvragen[/rml] kun je ongeveer zien hoe dat moet.

Oops! Google Chrome could not find www.rijks%20museum.nl


Verwijderd

Topicstarter
P_de_B schreef op dinsdag 22 november 2005 @ 10:02:
Je moet het gewoon niet op deze manier doen. Je kunt beter een autonummer veld gebruiken en die waarde uitlezen. In [rml][ Delphi] autoincrement van laatste INSERT-query opvragen[/rml] kun je ongeveer zien hoe dat moet.
"Dankje dat was zo gedaan, effe de query aangepast want werk precies het zelfde als bij delphi (ofja gewoon zoals sql werkt)

thanks _/-\o_" ;)

Nouja beetje te vroeg geroepen, want een keertje werkte wel, maar nu wil ik weer een record toevoegen en dan heeft in nog de oude new_id

Dus vraagt niet een nieuwe autonummer aan maar werkt dus op de session id van de gebruiker ?

maar zal effe verder zoeken.

[ Voor 22% gewijzigd door Verwijderd op 22-11-2005 10:24 ]


Verwijderd

Topicstarter
Oke ik heb wat anders ontdekt en vermoed dat de transactie als volgt werkt

Als ik mijn query's uitvoer in een transactie, dan wacht de server zo ie zo tot hij deze heeft afgehand voor hij verderen verzoeken toestaat. Klopt dit

Ik heb nammelijk volgende testje gedaan

een sleep in de transaction gezet van 30 seconden (3000)


Transaction in client 1 gestart
Transaction in client 2 gestart

Beide worden in volgorden uitgevoerd.

Dus transacties worden synchroon uitgevoerd eerst transaction 1 dan 2 ?

Klopt het wat ik zeg ? ;)

  • whoami
  • Registratie: December 2000
  • Laatst online: 17:16
Dat hangt er van af wat je doet in transactie 1 en transactie 2.
De server gaat nl. bepaalde dingen locken in transactie 1, en als transactie 2 diezelfde resources wil benaderen, dan moet transactie 2 wachten totdat transactie 1 afgelopen is.

Hoedanook, de manier waarop je werkt zoals je in je TS uitlegt moet tat vermeden worden.
Nouja beetje te vroeg geroepen, want een keertje werkte wel, maar nu wil ik weer een record toevoegen en dan heeft in nog de oude new_id

Dus vraagt niet een nieuwe autonummer aan maar werkt dus op de session id van de gebruiker ?
Kan niet.
Als je een record insert in een tabel met een autonumber column, dan krijgt dat record gewoon het volgende nummer, de DB zorgt ervoor dat die nummers uniek zijn binnen die tabel.
Ik denk dat jij iets fout doet; als je een record insert, en daarna een select @@identity doet, dan krijg je de waarde van het laatste toegewezen 'autonummer' veld binnen jouw sessie.

[ Voor 49% gewijzigd door whoami op 22-11-2005 12:13 ]

https://fgheysels.github.io/


Verwijderd

Topicstarter
whoami schreef op dinsdag 22 november 2005 @ 12:11:
Dat hangt er van af wat je doet in transactie 1 en transactie 2.
De server gaat nl. bepaalde dingen locken in transactie 1, en als transactie 2 diezelfde resources wil benaderen, dan moet transactie 2 wachten totdat transactie 1 afgelopen is.
Gaat hier om 2de zelfde transactions maar goed terug naar mij Select @@ indentity() want deze werkt gewoon mooier.

Ik gebruik hiervoor de volgende code en denk dus dat toch wel goed moet gaan aangezien ik netjes afsluit met een commit.

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
private void setPreOrder(object sender, System.EventArgs e)
{ 
    String connString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+ Server.MapPath("database/Orders.mdb") +";User Id=admin;Password=;"; 
    connectionOrders=new OleDbConnection(connString);
    connectionOrders.Open();

    OleDbTransaction transaction = connectionOrders.BeginTransaction();

    ordersCommand= new OleDbCommand();
    ordersCommand.Connection = connectionOrders;
    ordersCommand.Transaction = transaction;

    try
    {
        ordersCommand.CommandText = "SELECT @@IDENTITY AS newID";
        nieuwOrderRegelNummer = (int)ordersCommand.ExecuteScalar();
        
        Response.Write(nieuwOrderRegelNummer.ToString());

        sql = "SELECT MAX(Ordernr) As MaxOrderid From TBLOrders";
        ordersCommand.CommandText = sql;
        ordersDataReader = ordersCommand.ExecuteReader();

        while (ordersDataReader.Read())
        {
                nieuwOrderNummer = ((int)ordersDataReader["MaxOrderid"]);

        }
        ordersDataReader.Close();
        nieuwOrderNummer++;

        sql = "INSERT INTO TBLOrders ( Ordernr,Datum,Aantal,Bevestigd,Verwerkt) VALUES (";
        sql += nieuwOrderNummer + ", ";
        sql += " #01-10-2005# " + ", ";
        sql += IDAantal.Text + ", ";
        sql += " False " + ", ";
        sql += " False " + "  ); ";

        ordersCommand.CommandText = sql;
        ordersCommand.ExecuteNonQuery();

        sql = "INSERT INTO TBLKlantenOrders( KlantId, OrderNr) VALUES (";
        sql = sql + User.Identity.Name + ", ";
        sql = sql + nieuwOrderNummer + " ); ";

        ordersCommand.CommandText = sql;
        ordersCommand.ExecuteNonQuery();

        ArrayList Orderregels = getOrderRegels();

        for (int i = 0; i < Orderregels.Count; i++)
        {
            ArrayList tempArray = (ArrayList)Orderregels[i];
            String mrNumber, articleNumber, Omschrijving, carType, carModel, posistion;

            mrNumber = tempArray[0].ToString();
            articleNumber = tempArray[1].ToString();
            Omschrijving = tempArray[2].ToString();
            carType = tempArray[3].ToString();
            posistion = tempArray[4].ToString();
            carModel = tempArray[5].ToString();
            nieuwOrderRegelNummer++;

            sql = "INSERT INTO TBLOrderregels( Orderregelnr, Mnumber, Artikelnummer, Omschrijving, Type, Posistion, Model) VALUES (";
            sql += nieuwOrderRegelNummer + ",'" + mrNumber + "'," + articleNumber + ",'" + Omschrijving + "','" + carType + "','" + posistion + "','" + carModel + "');";

            ordersCommand.CommandText = sql;
            ordersCommand.ExecuteNonQuery();

            sql = "INSERT INTO TBLOrdersOrderregels( Ordernr, Orderregel) VALUES (";
            sql += nieuwOrderNummer + ", " + nieuwOrderRegelNummer + ");";

            ordersCommand.CommandText = sql;
            ordersCommand.ExecuteNonQuery();
        }
        transaction.Commit();
    }
    catch (Exception exp)
    {
        Response.Write(exp.ToString());
        transaction.Rollback();
    }
    finally
    {
        connectionOrders.Close();
    }
}


Is een lap code, maar dat heb ik geplaats om aan te geven hoe ik de Select@@Identity gebruik. Jullie hoeven hem niet te debuggen ;) Daarvoor is jullie tijd veels te kostbaar :P

  • whoami
  • Registratie: December 2000
  • Laatst online: 17:16
Jij gebruikt hem, zoals ik al gezegd heb, en zoals je dus kunt uit de documentatie opmaken, niet goed.
Je moet nl eerst inserten, en dan kan je pas de waarde opvragen van het autonumber-veld dat de DB aan jouw nieuw recordd heeft gegeven. (Zie ook het topic waar P_de_B al naar gelinkt heeft).

Jij doet eerst een select @@identity; wat wil je dan dat er gereturned wordt ? Je hebt nog niets geinserted.

(En lees ook eens iets over parametrized queries).

[ Voor 8% gewijzigd door whoami op 22-11-2005 12:40 ]

https://fgheysels.github.io/


Verwijderd

Topicstarter
whoami schreef op dinsdag 22 november 2005 @ 12:39:
Jij gebruikt hem, zoals ik al gezegd heb, en zoals je dus kunt uit de documentatie opmaken, niet goed.
Je moet nl eerst inserten, en dan kan je pas de waarde opvragen van het autonumber-veld dat de DB aan jouw nieuw recordd heeft gegeven. (Zie ook het topic waar P_de_B al naar gelinkt heeft).

Jij doet eerst een select @@identity; wat wil je dan dat er gereturned wordt ? Je hebt nog niets geinserted.

(En lees ook eens iets over parametrized queries).
Nu is het inderdaad wel gekukt, ik insert eerst en vraag het daarna op!
Levert me een behoorlijk besparing op aan het aantal regels, en moet nog korter kunnen. Maar dat zoek ik wel uit.

Is het trouwens mogelijk om de databank ook automatisch te herstellen zoals je dat in access kunt. Want nu is het zo als ik doorgenummerd heb dus 72,73,74, en gooi die weg (laatse record heeft nu nummer 71) hij toch verder gaat met 75. Is dit op te lossen ?

Maar in ieder geval bedankt

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
In principe is dit niet op te lossen, maar dat zou toch ook niet uit moeten maken? Het moet een gewoon 'dom' nummer zijn in mijn ogen waarbij het niet erg is dat er gaten in zitten.

Oops! Google Chrome could not find www.rijks%20museum.nl


Verwijderd

Topicstarter
P_de_B schreef op dinsdag 22 november 2005 @ 13:13:
In principe is dit niet op te lossen, maar dat zou toch ook niet uit moeten maken? Het moet een gewoon 'dom' nummer zijn in mijn ogen waarbij het niet erg is dat er gaten in zitten.
Ja maakt me in principe ook niet uit, is een ordernr, dat ik hem laat maken. Maar ja zou leuker zijn als ze beetje netjes ermee omgingen maar maakt ook iet uit.
Pagina: 1