Concorrenza per gestione DB

mercoledì 27 settembre 2006 - 15.07

bluland Profilo | Guru

Salve,

mi chiedevo come e' meglio gestire la concorrenza su un DB es. SQL Server 2000,
es. supponendo di avere una tabella di varie colonne, a cui possono accedere vari utenti da diverse postazioni, come si puo' gestire la classica situazione in cui due utenti agiscono piu o meno contemporaneamente sullo stesso record della stessa tabella?


saluti

Enzo

micto27 Profilo | Senior Member

>Salve,
>
>mi chiedevo come e' meglio gestire la concorrenza su un DB es.
>SQL Server 2000,
>es. supponendo di avere una tabella di varie colonne, a cui possono
>accedere vari utenti da diverse postazioni, come si puo' gestire
>la classica situazione in cui due utenti agiscono piu o meno
>contemporaneamente sullo stesso record della stessa tabella?

Io normalmente faccio così:

prevedo sulla tabella una colonna di tipo Timestamp, visto che ci pensa SQL Server a gestirla automaticamente
garantendone l'univocita nell'ambito della tabella e garantendone l'aggiornamento a fronte di qualsiasi UPDATE.

Quando l'applicazione acquisisce i dati legge anche i valori di tale colonna e al momento
di eseguire ad esempio un UPDATE aggiungo alle condizioni WHERE sulle colonne chiave una condizione sulla colonna
di tipo timestamp verificando che il valore sia ancora uguale a quello letto.

Ciao, Michele

bluland Profilo | Guru

>Io normalmente faccio così:
>
>prevedo sulla tabella una colonna di tipo Timestamp, visto che
>ci pensa SQL Server a gestirla automaticamente
>garantendone l'univocita nell'ambito della tabella e garantendone
>l'aggiornamento a fronte di qualsiasi UPDATE.

>
>Quando l'applicazione acquisisce i dati legge anche i valori
>di tale colonna e al momento
>di eseguire ad esempio un UPDATE aggiungo alle condizioni WHERE
>sulle colonne chiave una condizione sulla colonna
>di tipo timestamp verificando che il valore sia ancora uguale
>a quello letto.

si ma non ho capito una cosa,se ho una tabella che ad esempio

CREATE TABLE [Prenotazioni] ( [id] [decimal] (9), [NumeroStanza] [decimal] (9), [PrenotStart] datetime, [PrenotEnd] datetime, CONSTRAINT [PK_id] PRIMARY KEY CLUSTERED ( [id] ) ON [PRIMARY] ) ON [PRIMARY] GO

e piu o meno nello stesso momento viene effettuata una prenotaizone del tipo:

INSERT INTO [IAIA].[dbo].[Prenotazioni]([id], [NumeroStanza], [PrenotStart], [PrenotEnd]) VALUES(1,233,'20060927','20060930')

come si fa a decidere chi dei due avra prenotato la stanza??




>
>Ciao, Michele

micto27 Profilo | Senior Member


>INSERT INTO [IAIA].[dbo].[Prenotazioni]([id], [NumeroStanza],
>[PrenotStart], [PrenotEnd])
>VALUES(1,233,'20060927','20060930')
>
>come si fa a decidere chi dei due avra prenotato la stanza??

In una situazione come questa un'idea potrebbe essere definire un TRIGGER (per INSERT e UPDATE)
che valuti la presenza di eventuali altre righe, riferite allo stesso NumeroStanza, sovrapposte in base alle date
PrenoStart e PrenoEnd, facendo eventualmente fallire la transazione di inserimento/aggiornamento.

In questo caso se 2 client provano a prenotare periodi sovrapposti della stessa stanza,
il primo va a buon fine mentre il secondo fallirà.

Ciao, Michele.

bluland Profilo | Guru


>In una situazione come questa un'idea potrebbe essere definire
>un TRIGGER (per INSERT e UPDATE)
>che valuti la presenza di eventuali altre righe, riferite allo
>stesso NumeroStanza, sovrapposte in base alle date
>PrenoStart e PrenoEnd, facendo eventualmente fallire la transazione
>di inserimento/aggiornamento.
>
>In questo caso se 2 client provano a prenotare periodi sovrapposti
>della stessa stanza,
>il primo va a buon fine mentre il secondo fallirà.
>

quindi fare un controllo per update ed insert sui campi date?
questo da un lato mi inficerebbe la velocita di inserimento pero'...

>Ciao, Michele.

CIao ENzo
>

micto27 Profilo | Senior Member

>quindi fare un controllo per update ed insert sui campi date?
>questo da un lato mi inficerebbe la velocita di inserimento pero'...
>CIao ENzo
>>
>

si tratterebbe di un controllo verosimilmente molto rapido,
non credo che l'onere aggiuntivo per il database sarebbe
rilevante.
Qualcosa del tipo:

CREATE trigger trCheckPrenotazione on dbo.Prenotazioni FOR INSERT, UPDATE AS if exists (select 1 from Prenotazioni p inner join inserted w on w.NumeroStanza = p.NumeroStanza and w.id <> p.id and w.PrenotStart <= p.PrenotEnd and w.PrenotEnd >= p.PrenotStart) begin RAISERROR ('La disponibilità è cambiata, impossibile prenotare la/le stanze....', 16, 1) ROLLBACK TRANSACTION end

ciao, Michele

lbenaglia Profilo | Guru

>
>>INSERT INTO [IAIA].[dbo].[Prenotazioni]([id], [NumeroStanza],
>>[PrenotStart], [PrenotEnd])
>>VALUES(1,233,'20060927','20060930')
>>
>>come si fa a decidere chi dei due avra prenotato la stanza??
>
>In una situazione come questa un'idea potrebbe essere definire
>un TRIGGER (per INSERT e UPDATE)
>che valuti la presenza di eventuali altre righe, riferite allo
>stesso NumeroStanza, sovrapposte in base alle date
>PrenoStart e PrenoEnd, facendo eventualmente fallire la transazione
>di inserimento/aggiornamento.

In questo caso basterebbe un banale UNIQUE constraint senza scomodare alcun trigger. Nel caso la stanza sia già prenotata per una certa data verrà sollevata una eccezione di violazione del constraint che andrà intercettata lato client.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

micto27 Profilo | Senior Member

>In questo caso basterebbe un banale UNIQUE constraint senza scomodare
>alcun trigger. Nel caso la stanza sia già prenotata per una certa
>data verrà sollevata una eccezione di violazione del constraint
>che andrà intercettata lato client.

Immagino che la prenotazione possa essere per periodi diversi
e i periodi potrebbero essere sovrapposti pur non avendo le
stesse date inizio e fine, quindi non credo che un indice UNIQUE
potrebbe aiutare.

Michele

bluland Profilo | Guru

>Immagino che la prenotazione possa essere per periodi diversi
>e i periodi potrebbero essere sovrapposti pur non avendo le
>stesse date inizio e fine, quindi non credo che un indice UNIQUE
>potrebbe aiutare.

nel caso di una stanza di hotel non potrebbe verificarsi, poiche se il periodo è prenotato è prenotato,
quindi sembra un pò che tutto dipende dallo specifico caso, con la unique come funzionerebbe?


>Michele

CIao
>
>

micto27 Profilo | Senior Member

>>Immagino che la prenotazione possa essere per periodi diversi
>>e i periodi potrebbero essere sovrapposti pur non avendo le
>>stesse date inizio e fine, quindi non credo che un indice UNIQUE
>>potrebbe aiutare.
>
>nel caso di una stanza di hotel non potrebbe verificarsi, poiche
>se il periodo è prenotato è prenotato,
>quindi sembra un pò che tutto dipende dallo specifico caso, con
>la unique come funzionerebbe?

Se i periodi per una stanza sono fissi e quindi non possono esistere 2 righe con NUmero stanza
e data inizio uguali allora devi definire un indice con il controllo dell'univocità, comprendente le colonne
NumeroStanza e PrenotStart.

-- se basta un controllo di univocità: ALTER TABLE dbo.Prenotazioni ADD CONSTRAINT IX_Prenotazioni UNIQUE NONCLUSTERED ( NumeroStanza, PrenotStart ) ON [PRIMARY] GO -- se vuoi che venga costruito fisicamente anche l'indice CREATE UNIQUE NONCLUSTERED INDEX IX_Prenotazioni ON dbo.Prenotazioni ( NumeroStanza, PrenotStart ) ON [PRIMARY] GO

Ciao

lbenaglia Profilo | Guru

>-- se basta un controllo di univocità:
>ALTER TABLE dbo.Prenotazioni ADD CONSTRAINT
> IX_Prenotazioni UNIQUE NONCLUSTERED
> (
> NumeroStanza,
> PrenotStart
> ) ON [PRIMARY]
>
>GO
>
>-- se vuoi che venga costruito fisicamente anche l'indice
>CREATE UNIQUE NONCLUSTERED INDEX IX_Prenotazioni ON dbo.Prenotazioni
> (
> NumeroStanza,
> PrenotStart
> ) ON [PRIMARY]
>GO

Attenzione, un constraint UNIQUE garantisce l'univocità creando fisicamente un indice unique, peranto dal punto di vista fisico non sussiste alcuna differenza. La grossa differenza è a livello logico: un constraint è un vincolo sui dati che ne determina la validità, mentre un indice è una struttura dati che serve per velocizzare gli accessi ad una tabella.

Se vuoi approfondire l'argomento leggi i seguenti post:

Cos'è un constraint:
http://tinyurl.com/6bahc

Cos'è un indice:
http://tinyurl.com/69gbe

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

micto27 Profilo | Senior Member

Grazie,

ciao Michele
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5