Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Transakcje bazodanowe, poziomy izolacji
Forum PHP.pl > Forum > Bazy danych > MySQL
kisialala
Cześć.

Pracuję nad projektem aplikacji ankiet uczelnianych. Opracowałem schemat bazy danych. Niestety nie mogę sobie poradzić z transakcjami do procedur i funkcji.

Bardzo proszę o pomoc w utworzeniu poziomów izolacji transakcji i informację dlatego tak a nie inaczej. Wszędzie wydaje mi się sensowne jedynie read commited :/

OPIS TABEL:
ankiety_wypelnione - przechuje informacje o tym, kto wypełnił ankietę ( później nie może już jej wyświetlić )
historia - zapisuje informacje o zmianach ( w nazwach ankiety, treści pytania )
pytania - przechowuje pytania przypisane do ankiet
pytania_typy - przechowuje informacje o typach pytań ( taknie, ocena, tekstowa itp; w każdej chwili można dodać nowe typy )
odpowiedzi - tabela odpowiedzi do pytań ( anonimowe, nie można wiedzieć jaki użytkownik udzielił daną odpowiedź )
odpowiedzi_archiwum - tabelka archiwalna wypełniana co określony czas za pomocą eventu
ankiety - przechowuje informacje o utworzonych ankietach ( nazwa, data otwarcia, data zamknięcia, informacja o tym do jakiego przedmiotu ją przypisujemy )
uzytkownicy - tabelka do zalogowania, konta użytkowników ( wspólna dla studentów, pracowników, administratorów itd )
uzytkownicy_typy - typy użytkowników ( np: student, wykładowca, administrator itd; w kazdej chwili można dodać nowe typy )
prowadzacy - tabela przypisuje użytkowników ( wykładowców ) do przedmiotów na danych wydziałach i kierunkach ( prowadzący może prowadzić wiele przedmiotów na różnych wydziałach, przedmioty mogą mieć wielu prowadzących )
studenci_przedmioty - przypisujemy studentów do przedmiotów na danych kierunkach ( po to aby móc wyświetlić im stosowne ankiety )
kierunki_przedmioty - tabelka złączeniowa przypisująca przedmioty do kierunków
przedmioty - tabela przechowuje przedmioty
kierunki - tabela kierunków ( są przypisane do wydziałów )
wydziały - tabela wydziałów


OPIS PROCEDUR I FUNKCJI:
archiwizuj_odpowiedzi - procedura wywoływana raz w roku co event, przenosi stare odpowiedzi do archiwum
dodaj_studenta - procedura dodawania nowego studenta
ile_uprawnionych - funkcja zwracająca liczbę uprawnionych do wypełnienia ankiety
ile_wypełniło - funkcja zwraca liczbę osób, które wypełniło ankietę
odpowiedz - procedura odpowiedzi na dane pytanie
srednia_pytania - funkcja zwraca średnią liczbę oceń dla pytań typu "ocena"
zaktualizuj_pytanie - funkcja umożliwiająca aktualizację treść pytania, jeśli nikt jeszcze nie udzielił na nie odpowiedzi



  1. CREATE PROCEDURE `archiwizuj_odpowiedzi`()
  2. BEGIN
  3. SET session transaction isolation level READ committed;
  4.  
  5. INSERT INTO odpowiedzi_archiwum SELECT * FROM odpowiedzi WHERE odpowiedzi_data < DATE_SUB(CURDATE(), INTERVAL 1 YEAR);
  6. DELETE FROM odpowiedzi WHERE odpowiedzi_data < DATE_SUB(CURDATE(), INTERVAL 1 YEAR);
  7.  
  8. commit;
  9. END
  10.  
  11.  
  12. CREATE PROCEDURE `dodaj_studenta`(`login` varchar(50),`haslo` varchar(50),`email` varchar(50),`imie` varchar(50),`nazwisko` varchar(80),`typ` varchar(30))
  13. BEGIN
  14. DECLARE TYPY_ID INTEGER;
  15. DECLARE USER_COUNT INTEGER;
  16. SET session transaction isolation level READ uncommitted;
  17.  
  18. SELECT uzytkownicytypy_id INTO TYPY_ID FROM uzytkownicy_typy WHERE uzytkownicytypy_nazwa = typ;
  19.  
  20. SELECT COUNT(*) INTO USER_COUNT FROM uzytkownicy WHERE uzytkownicy_login = login OR uzytkownicy_email = email;
  21.  
  22. IF TYPY_ID > 0 AND USER_COUNT = 0 THEN
  23. INSERT INTO uzytkownicy(uzytkownicy_id,uzytkownicy_login,uzytkownicy_haslo,uzytkownicy_email,uzytkownicy_imie,uzytkownicy_nazwisko,uzytkownicytypy_id) VALUES(NULL,login,haslo,email,imie,nazwisko,TYPY_ID);
  24. END IF;
  25.  
  26. commit;
  27. END
  28.  
  29.  
  30. CREATE FUNCTION `ile_uprawnionych`(`ankieta` int) RETURNS int(11)
  31. BEGIN
  32. declare studenci int;
  33. declare kierunek int;
  34. declare kierunkiprzedmioty int;
  35.  
  36. SELECT kierunkiprzedmioty_id INTO kierunkiprzedmioty FROM ankiety WHERE ankiety_id = ankieta;
  37. SELECT count(studenciprzedmioty_id) INTO studenci FROM studenci_przedmioty WHERE kierunkiprzedmioty_id = kierunkiprzedmioty;
  38.  
  39. RETURN studenci;
  40. END
  41.  
  42.  
  43.  
  44. CREATE FUNCTION `ile_wypelnilo`(`ankieta` int) RETURNS int(11)
  45. BEGIN
  46. declare liczba int;
  47. SELECT count(*) INTO liczba FROM ankiety_wypelnione WHERE ankiety_id = ankieta;
  48.  
  49. RETURN liczba;
  50. END
  51.  
  52.  
  53.  
  54.  
  55. CREATE PROCEDURE `odpowiedz`(`pytanie` int, `odpowiedz` varchar(500))
  56. BEGIN
  57. declare ocena int;
  58. declare typ int;
  59. declare odp varchar(500);
  60. SET odp = cast(odpowiedz AS UNSIGNED);
  61. SET session transaction isolation level READ committed;
  62.  
  63. SELECT pytaniatypy_id INTO ocena FROM pytania_typy WHERE pytaniatypy_nazwa = 'ocena';
  64. SELECT pytaniatypy_id INTO typ FROM pytania WHERE pytania_id = pytanie;
  65. IF pytanie > 0 then
  66. IF typ = ocena then
  67. IF odp > 0 then
  68. INSERT INTO odpowiedzi (odpowiedzi_id,pytania_id,odpowiedzi_tresc,odpowiedzi_data) VALUES(NULL,pytanie,odpowiedz,NOW());
  69. end IF;
  70. else
  71. INSERT INTO odpowiedzi (odpowiedzi_id,pytania_id,odpowiedzi_tresc,odpowiedzi_data) VALUES(NULL,pytanie,odpowiedz,NOW());
  72. end IF;
  73. end IF;
  74.  
  75. commit;
  76. END
  77.  
  78.  
  79.  
  80. CREATE FUNCTION `srednia_pytania`(`pytania` int) RETURNS int(11)
  81. BEGIN
  82. declare liczba int;
  83. SELECT avg(odpowiedzi.odpowiedzi_tresc) INTO liczba FROM odpowiedzi, pytania WHERE pytania.pytaniatypy_id = 2 AND odpowiedzi.pytania_id = pytania;
  84.  
  85. RETURN liczba;
  86. END
  87.  
  88.  
  89.  
  90. CREATE PROCEDURE `zaktualizuj_pytanie`(`pytanie` int,`tresc` varchar(255))
  91. BEGIN
  92.  
  93. declare lo integer;
  94.  
  95. SET session transaction isolation level READ committed;
  96.  
  97. SELECT count(*) INTO lo FROM odpowiedzi WHERE pytania_id = pytanie;
  98. IF lo = 0 then
  99. UPDATE pytania SET pytania_tresc = tresc WHERE pytania_id = pytanie;
  100. end IF;
  101.  
  102. commit;
  103. END
  104.  
pasman
transakcje w procedurach używa się trochę inaczej.

stackoverflow


poziomy izolacji różne od read committed są istotne gdy kilku klientów zmienia te same dane.
przy wypełnianiu ankiet taka sytuacja raczej się nie zdarza - jedna osoba wypełnia jedną ankietę.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.