/ Forside / Teknologi / Udvikling / SQL / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
SQL
#NavnPoint
pmbruun 1704
niller 962
fehaar 730
Interkril.. 701
ellebye 510
pawel 510
rpje 405
pete 350
gibson 320
10  smorch 260
SP: Lås tabel, og start transaktion
Fra : Casper Bang


Dato : 13-01-05 12:47

Hej,

I en stored procedure i MS SQL Server 2000 vil jeg starte en
læse/skrive-lås, samt starte en transaktion.
Hvis det er muligt, skal låsen selv finde ud af kun at låse de records den
hiver fat i, og returnere en fejl hvis den prøver at hive fat i en låst
record. Ved den fejl afsluttes og laves en rollback på transaktionen.
De låste records skal først låses op igen, når transaktionen afsluttes.

Kan man det? Hvis ja, hvordan?

Tak!
~Casper



 
 
Casper Bang (13-01-2005)
Kommentar
Fra : Casper Bang


Dato : 13-01-05 15:07

[SNIP]

En anden løsning der kunne bruges, som jeg ikke ved om findes, og om er
nemmere end det andet er:
Lås en SP; indtil en given SP er færdig med at køre, kan INGEN andre få fat
i denne SP

Kan det lade sig gøre nemmere end det andet?

Tak :)



Jesper Sommer (14-01-2005)
Kommentar
Fra : Jesper Sommer


Dato : 14-01-05 03:06

> I en stored procedure i MS SQL Server 2000 vil jeg starte en
> læse/skrive-lås, samt starte en transaktion.
> Hvis det er muligt, skal låsen selv finde ud af kun at låse de records den
> hiver fat i, og returnere en fejl hvis den prøver at hive fat i en låst
> record. Ved den fejl afsluttes og laves en rollback på transaktionen.
> De låste records skal først låses op igen, når transaktionen afsluttes.
>
> Kan man det? Hvis ja, hvordan?

Nu spørger jeg måske dumt, men kan man ikke lave en SELECT FOR UPDATE på
en MS SQL server ? Så finder basen jo selv ud af at låse de records
(eller sikkert hele den side) som dit statement rammer ?

Måske hedder formuleringen noget andet i MS Transact SQL, men hvis du
kan lave noget der smager af SELECT FOR UPDATE så er du jo halvt færdig.
Og så skal du måske overveje at lave færdige transaktioner (BEGIN
TRANSACTION) i stedet for selv at styre låse og roll-backs ...




Venligst


- Jesper

Casper Bang (14-01-2005)
Kommentar
Fra : Casper Bang


Dato : 14-01-05 11:52

> Nu spørger jeg måske dumt, men kan man ikke lave en SELECT FOR UPDATE på
> en MS SQL server ? Så finder basen jo selv ud af at låse de records (eller
> sikkert hele den side) som dit statement rammer ?

Hmm.. jeg kan ikke finde noget om det ved søgning på "SELECT FOR UPDATE ms
sql" - umidelbart findes den ikke til MS SQL Server - i hvert fald ikke med
det navn.


> Måske hedder formuleringen noget andet i MS Transact SQL, men hvis du kan
> lave noget der smager af SELECT FOR UPDATE så er du jo halvt færdig. Og så
> skal du måske overveje at lave færdige transaktioner (BEGIN TRANSACTION) i
> stedet for selv at styre låse og roll-backs ...

Ja, BEGIN TRANSACTION og COMMIT TRANSACTION virker.
Nu skal jeg bare have den til at låse de tabeller den har fat i :)

Problemet er at min SP bliver kaldt ret tit - men hvis to personer hiver fat
i den SP på samme tid, er der risiko for problemer med lost updates.
Men hvis der ikke er en relativt simpel kommando til at gøre det med, må jeg
kode mig uden om problemet, ved at sætte nogle milestones som den tjekker op
på (som bruges til at låse SPen).

Tak



Jesper Sommer (15-01-2005)
Kommentar
Fra : Jesper Sommer


Dato : 15-01-05 21:16

> Hmm.. jeg kan ikke finde noget om det ved søgning på "SELECT FOR UPDATE ms
> sql" - umidelbart findes den ikke til MS SQL Server - i hvert fald ikke med
> det navn.

Det er vist en gammel ANSI SQL ting, så det fatter jeg ikke. Skomager
metoden kunne være at anvende LOCK TABLE i din SP, men det er jo både
grimt og farligt.

Der MÅ altså findes noget tilsvarende. Jeg er på ingen måde ekspert, men
en cursor med indbygget lås er ikke nogen revolutionerende nyhed i en
veludviklet kommerciel RDBMS.

Øjeblik ...

Jeg fandt følgende afsnit efter lidt søgen:

"Finally, as we said before, in versioning databases reads don't lock
writes, which might be what we want. Is this possible with a versioning
database? Locking-database programmers, when using versioning, tend to
lock too little, introducing subtle concurrency problems. In a
versioning database, there must be a way to do insist on a lock on read.
Ordinarily this is done by doing a SQL SELECT FOR UPDATE. But SQL Server
does not support SELECT FOR UPDATE with the appropriate semantic. There
is, however, a solution. Even when READ_COMMITTED_SNAPSHOT is on, you
can ensure a read lock by using SQL Server's REPEATABLE READ isolation
level, which never does versioning. The SQL Server equivalent of ANSI's
SELECT FOR UPDATE is SELECT with (REPEATABLEREAD). Note that this is
different from the SQL Server UPDLOCK (update lock), which is a special
lock that has similar semantics but only works if all participants in
all transactions are using UPDLOCK. This is one place where programs
written for versioning databases may have to change their code in
porting to SQL Server 2005."
KILDE:
http://www.awprofessional.com/articles/article.asp?p=327394&seqNum=2)


Jeg fandt også følgende oversigt over, hvilke databaser der understøtter
SELECT ... FOR UPDATE. Den er fantisk ganske god. Resten af artiklen
skal du dog ikke hænge dig i, fordi den omhandler en specifik database
universel database driver.
LINK:
http://www.versant.com/resources/documentation/voajdocs/transactions.html


Det er en meget gammel problematik du står over for, og dybest set er
jeg fristet til at henvise dig til programmeringsgruppen. Her kan vi så
tage hul på et gammelt "Design Pattern" der hedder Model View Controller
(MVC) som specifikt er beregnet til at løse dit problem. Men altså ikke
på database nuveau, men på applikationsniveau

Venligst


- Jesper

Jesper Sommer (15-01-2005)
Kommentar
Fra : Jesper Sommer


Dato : 15-01-05 21:30

.... og venligst ignorer diverse klippe-klistre-og-slå-fejl som jeg
allerede selv har spottet ...

- Jesper

Stig Johansen (15-01-2005)
Kommentar
Fra : Stig Johansen


Dato : 15-01-05 21:39

Jesper Sommer wrote:

[snip]
> Jeg fandt følgende afsnit efter lidt søgen:
>
> "Finally, as we said before, in versioning databases reads don't lock
> writes, which might be what we want. Is this possible with a versioning
> database? Locking-database programmers, when using versioning, tend to
> lock too little, introducing subtle concurrency problems.

Vær opmærksom på, at MS SQLServer 2K *ikke* er en versioning database.

--
Med venlig hilsen
Stig Johansen

Jesper Sommer (15-01-2005)
Kommentar
Fra : Jesper Sommer


Dato : 15-01-05 22:22

>>"Finally, as we said before, in versioning databases reads don't lock
>>writes, which might be what we want. Is this possible with a versioning
>>database? Locking-database programmers, when using versioning, tend to
>>lock too little, introducing subtle concurrency problems.
>
> Vær opmærksom på, at MS SQLServer 2K *ikke* er en versioning database.

Det er jo også netop hvad artiklen i linket påpeger ...

Venligst


- Jesper

Stig Johansen (15-01-2005)
Kommentar
Fra : Stig Johansen


Dato : 15-01-05 21:36

Casper Bang wrote:

[Snip - låsnings problematik]
> Ja, BEGIN TRANSACTION og COMMIT TRANSACTION virker.
> Nu skal jeg bare have den til at låse de tabeller den har fat i :)

Jeg er rimelig sikker på, at MSSQL Server *selv* sørger for passende
låsninger inden i en transaktion.

> Problemet er at min SP bliver kaldt ret tit - men hvis to personer hiver
> fat i den SP på samme tid, er der risiko for problemer med lost updates.

Kan du uddybe problemstillingen?
Hvis der er 2, der forsøger samme update på 'samme' tid, venter nummer 2 til
nummer 1 er færdig (commit/rollback), subsidiært udnævnes til deadlock
victim.

> Men hvis der ikke er en relativt simpel kommando til at gøre det med, må
> jeg kode mig uden om problemet, ved at sætte nogle milestones som den
> tjekker op på (som bruges til at låse SPen).

Igen, kan du uddybe hvad dit /egentlige/ problem er?

--
Med venlig hilsen
Stig Johansen

Jesper Sommer (15-01-2005)
Kommentar
Fra : Jesper Sommer


Dato : 15-01-05 21:44

> Jeg er rimelig sikker på, at MSSQL Server *selv* sørger for passende
> låsninger inden i en transaktion.

Det gør de sikkert også - men hvad med i en Stored Procedure der ikke er
defineret som transaktioner ?

Hvis du selv er en haj til MS SQL, har du så et bud på hvordan man
udfører et alternativt til "SELECT ... FOR UPDATE" på en MS SQL, når nu
dette ikke supporteres direkte ?



Venligst


- Jesper

Stig Johansen (16-01-2005)
Kommentar
Fra : Stig Johansen


Dato : 16-01-05 05:32

Jesper Sommer wrote:

>> Jeg er rimelig sikker på, at MSSQL Server *selv* sørger for passende
>> låsninger inden i en transaktion.
>
> Det gør de sikkert også - men hvad med i en Stored Procedure der ikke er
> defineret som transaktioner ?

Jeg udtrykte mig måske lidt uklart men med transaktion mener jeg statements,
der bliver udført fra BEGIN TRANS til COMMIT eller ROLLBACK.
Eksempelvis
BEGIN TRANS
SELECT Navn FROM Kunder WHERE KundeNr=123456 -- Her låses
UPDATE Kunder SET Navn=NytNavn WHERE KundeNr=123456 -- Stadig låst
COMMIT -- Her frigives låsen

> Hvis du selv er en haj til MS SQL,

One never knows, men man har da kodet nod diverse databaser i diverse sprog
på diverse platforme i ca 1/4 århundrede.

> har du så et bud på hvordan man
> udfører et alternativt til "SELECT ... FOR UPDATE" på en MS SQL, når nu
> dette ikke supporteres direkte ?

Ja, kig på pessimistic locking, og implicit transactions m.v.

Men som nævnt, beskriver du ikke (i mine øjne) din reelle problemstilling.
Det jeg kan forholde mig til (fra dine indlæg) er:
.....
returnere en fejl hvis den prøver at hive fat i en låst
record
......
Jeg bruger ikke selv den slags metoder, så du må selv undersøge om MS
SQLServer giver en fejl/exception ved brug af pessimistic locking.

......
men hvis to personer hiver fat
i den SP på samme tid, er der risiko for problemer med lost updates
......
Det er denne her, der er tåget. Hvad mener du med 'lost updates'?
Som nævnt, venter nummer 2 bare til 1 er færdig. Der er ikke noget, der
bliver 'lost'.

--
Med venlig hilsen
Stig Johansen

Casper Bang (16-01-2005)
Kommentar
Fra : Casper Bang


Dato : 16-01-05 09:52

> Jeg udtrykte mig måske lidt uklart men med transaktion mener jeg
> statements,
> der bliver udført fra BEGIN TRANS til COMMIT eller ROLLBACK.
> Eksempelvis
> BEGIN TRANS
> SELECT Navn FROM Kunder WHERE KundeNr=123456 -- Her låses
> UPDATE Kunder SET Navn=NytNavn WHERE KundeNr=123456 -- Stadig låst
> COMMIT -- Her frigives låsen

Jeg var ikke klar over at SQL Server låste på den måde i en transaktion.
I det tilfælde klarer transaktionen det hele :)

Jeg beklager at jeg var lidt utydelig i min problemstilling.
Løsningen lå dog i at starte en simpel transaktion.

Tak for hjælpen!
Casper



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408924
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste