Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

MS SQL - transakcje i DataSety

5 views
Skip to first unread message

speedy10...@gmail.com

unread,
Jun 7, 2008, 1:37:20 PM6/7/08
to
Witam

Mam pytanie jak programowo w c# obsłużyć transakcje, baza danych to MS
SQL Express, korzystam z DataSetów.

przykładowa transakcja:

1. początek transakcji,
2. wykonuje sprawdzenie czy user o danym loginie istnieje (select),
(po tym kroku nikt nie powinnien móc wywołać funkcji sprawdzającej)
3. jeśli nie było usera o podanym loginie dodaje lub uaktualniam dane
w bazie (update),
4. koniec transakcji,
(dopiero tutaj następny user może wywołać funckje sprawdzającą -
selecta na tabeli).

W rozwiazaniu, którego używam tabela jest blokowana dopiero po
wykonaniu update'a do bazy, ale to jest za późno, ustawiłem też
isolation level na najbardziej restrykcyjny i róznież nic.

Potrzebuje rozwiązania, które zagwarantuje mi, że żaden user nie
odczyta danych z tabeli po wykonaniu się selecta w podanej wyżej
transakcji i dostęp do bazy zostanie zwolniony po zakończeniu
transakcji.
Rozwiązanie musi opierać się na oprogramowaniu DataSetów - aplikacja w
tej chwili z nich korzysta i nie chcę tego zmieniać jedynie dodać
transakcje.

Proszę o pomoc, dobre rady, wskazówki.

Pozdrawiam

Wiktor Zychla

unread,
Jun 9, 2008, 4:12:20 AM6/9/08
to
> W rozwiazaniu, którego używam tabela jest blokowana dopiero po
> wykonaniu update'a do bazy, ale to jest za późno, ustawiłem też

? możesz to rozwinąć ?

> Rozwiązanie musi opierać się na oprogramowaniu DataSetów - aplikacja w

nie musi, jeśli to jest kawałek procesu biznesowego w architekturze
trójwarstwowej, to użyj mechanizmu synchronizacji wątków - będzie prościej i
bezpieczniej, w razie wywrotki kodu nie zostaniesz z zablokowanym serwerem
bazy danych, czekającym na zwolnienie blokady przez proces, które nigdy nie
nastąpi.

jeśli to koniecznie musi być po stronie sqla, to próbuj blokadami
aplikacyjnymi (sp_getapplock, sp_releaseapplock).

Wiktor Zychla

Message has been deleted

speedy10...@gmail.com

unread,
Jun 10, 2008, 2:04:00 AM6/10/08
to
> > W rozwiazaniu, którego używam tabela jest blokowana dopiero po
> > wykonaniu update'a do bazy, ale to jest za późno, ustawiłem też

> ? możesz to rozwinąć ?

w kodzie wyglada to następująco:
część funkcji dodającej nowego usera

try{
transaction =
sqlConnection.BeginTransaction(IsolationLevel.Serializable);
row = operatorTable.NewOperatorRow();

using (FrmAdminOperator frm = new
FrmAdminOperator(row))
{
//przekazuje transakcje do forms (nie jest to
piękne ale musi zostać), w tej formie jest funkcja sprawdzająca, czy
dany operator (user) istnieje
frm.Transaction = transaction;
frm.Text = "Nowy operator";
if (frm.ShowDialog() == DialogResult.OK)
{
row.EndEdit();
operatorTable.AddOperatorRow(row);
updateRow(row, transaction);
transaction.Commit();

//loguje wykonaną operacje do bazy
log.Log(LogOperacja.Dodanie, row.ID);
}
}
}
catch (Exception ex)
{
transaction.Rollback();
operatorTable.RejectChanges();
Msg.Exception(ex, "Wystąpił podczas dodawania
użytkownika!");
}
fillData();
}

-------------------------------------------------------------------------
funkcja z formy

private bool operatorExists(string login)
{
bool flag = false;
try
{
using (OperatorTableAdapter ta = new
OperatorTableAdapter())
{
ta.Connection = _transaction.Connection;
ta.SetTransaction(_transaction);

//tutaj wywołany zostaje funckaj (select), która
powinna blokować odczyt innym userów, aby nie mogli sprawdzić, czy
user o podanym loginie istnieje,
//ponieważ w innej sesji może właśnie odbywać się
update loginu innego usera

flag = (int)ta.CountByLogin(login) > 0 ? true :
false;
}
return flag;
}
catch {
MsgCollection message = new MsgCollection("W
formularzu wystąpiły błędy");
message.Add(new Msg("Wystąpiły błędy podczas
sprawdzania unikalności loginu!", MsgType.Error));
}

return flag;
}

> > Rozwiązanie musi opierać się na oprogramowaniu DataSetów - aplikacja w

> nie musi, jeśli to jest kawałek procesu biznesowego w architekturze
> trójwarstwowej, to użyj mechanizmu synchronizacji wątków - będzie prościej i
> bezpieczniej, w razie wywrotki kodu nie zostaniesz z zablokowanym serwerem
> bazy danych, czekającym na zwolnienie blokady przez proces, które nigdy nie
> nastąpi.

Zablokowania serwera nie przewidziałem:/

Aplikacja niestety nie jest w architekturze trójwarstwowej, łączy się
bezpośrednio z serwerem baz danych.
Myślałem też o korzystaniu z transactionScope'ów, które działają
dobrze w tej sytuacji, ale nie wiem czy to dobry pomysł?

> jeśli to koniecznie musi być po stronie sqla, to próbuj blokadami
> aplikacyjnymi (sp_getapplock, sp_releaseapplock).

> Wiktor Zychla

Dziękuje i pozdrawiam

Wiktor Zychla

unread,
Jun 10, 2008, 4:00:53 AM6/10/08
to
> Nigdy nie korzystałem z synchronizacji wątków w architekturze

myślę o zwykłej synchronizacji wątków w procesie serwera aplikacji. to ma
oczywiście wadę, polegającą na błędnym działaniu w scenariuszu farmy
serwerów aplikacji, ale na jednym serwerze będzie działać jak najbardziej
poprawnie.

Wiktor Zychla

speedy10...@gmail.com

unread,
Jun 14, 2008, 12:32:39 PM6/14/08
to

Dziękuje za pomoc.

0 new messages