105 Technologie odwzorowania owania obiektowo-relacyjnego relacyjnego: Oracle TopLink
Plan prezentacji 106 Wprowadzenie TopLink Workbench TopLink w JDeveloper 10g Wybrane metody odwzorowania obiektowo-relacyjnego Zarządzanie sesjami TopLink Realizacja zapytań dynamicznych Obsługa tożsamości obiektów Przetwarzanie transakcyjne
TopLink: : Przeznaczenie produktu 107 Warstwa komunikacji aplikacji Java z bazą danych, oparta na koncepcji odwzorowania obiektowo-relacyjnego Projektant aplikacji w języku XML definiuje zasady odwzorowań obiektów Java na rekordy tabel bazy danych Aplikacja Java wykorzystuje TopLink API w celu komunikacji z warstwą TopLink; warstwa TopLink przekształca wywołania aplikacyjne w komendy SQL przekazywane do systemu zarządzania bazą danych poprzez JDBC Aplikacja Java TopLink Runtime Engine JDBC Baza danych Definicja odwzorowania
TopLink: : historia 108 Opracowany na początku lat dziewięćdziesiątych przez firmę WebGain jako platforma usługowa w środowisku Smalltalk W 1996 roku przeniesiony do języka Java Firma WebGain przejęta przez Oracle, TopLink włączony do Oracle9i
TopLink: : Cykl rozwoju aplikacji 109 Projektowanie i implementacja relacyjnej bazy danych Projektowanie i implementacja obiektowego modelu danych w języku Java Definicja odwzorowań obiektowo-relacyjnych pomiędzy obiektami Java a rekordami tabel w bazie danych (metadane) Implementacja kodu przetwarzania danych w języku Java tabele klasy xml metadane (projekt TopLink)
TopLink: : Narzędzia 110 JDeveloper 10g R3 zawiera kreatory i edytory odwzorowań TopLink TopLink Workbench to samodzielna aplikacja Java służąca do definicji i edycji odwzorowań TopLink Biblioteka TopLink API
TopLink: : Definicje 111 Deskryptor (descriptor) - opisuje powiązanie pomiędzy klasą Java a tabelą w bazie danych Odwzorowanie (mapping) - opisuje powiązanie pomiędzy atrybutem klasy a kolumną tabeli Projekt (project) - gromadzi wszystkie deskryptory i odwzorowania dla całej aplikacji
TopLink: : Projekt 112 Projekt jest kontenerem zawierającym wszystkie metadane niezbędne do realizacji odwzorowań obiektowo-relacyjnych Formy reprezentacji projektów TopLink: plik XML do dynamicznego użycia podczas wykonania aplikacji klasa Java zawierająca kod odwzorowań obiektowo-relacyjnych do statycznego użycia podczas wykonywania aplikacji plik WMP wykorzystywany przez TopLink Workbench
TopLink: : Projekt w postaci pliku XML 113 <?xml version="1.0" encoding="utf-8"?> <toplink:object-persistence version="oracle TopLink - 10g" xmlns:opm="http://xmlns.oracle.com/ias/xsds/opm" xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:toplink="http://xmlns.oracle.com/ias/xsds/toplink" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"> <opm:name>myproj1</opm:name> <opm:class-mapping-descriptors> <opm:class-mapping-descriptor xsi:type="toplink:relational-class-mapping-descriptor"> <opm:class>package1.dept</opm:class> <opm:alias>dept</opm:alias> <opm:primary-key> <opm:field table="dept" name="deptno" xsi:type="opm:column"/> </opm:primary-key> <opm:events xsi:type="toplink:event-policy"/> <opm:querying xsi:type="toplink:query-policy"/> <opm:attribute-mappings> <opm:attribute-mapping xsi:type="toplink:direct-mapping"> <opm:attribute-name>nazwa</opm:attribute-name> <opm:field table="dept" name="dname" xsi:type="opm:column"/> </opm:attribute-mapping>...
TopLink: : Projekt w postaci klasy Java 114 import oracle.toplink.sessions.*; import oracle.toplink.descriptors.*;... import oracle.toplink.sequencing.*; public class MyProj1 extends oracle.toplink.sessions.project { public MyProj1() { setname("test"); applylogin(); adddescriptor(buildempdescriptor()); adddescriptor(builddeptdescriptor());} public void applylogin() { DatabaseLogin login = new DatabaseLogin(); login.useplatform( new oracle.toplink.platform.database.oracle.oracle10platform()); login.setdriverclassname("oracle.jdbc.driver.oracledriver"); login.setconnectionstring("jdbc:oracle:thin:@localhost:1521:orcl"); login.setusername("scott"); login.setencryptedpassword("3e20f8982c53f4aba825e30206ec8ade");...
115 Definiowanie odwzorowań obiektowo-relacyjnych za pomocą narzędzia TopLink Workbench
Definiowanie odwzorowań obiektowo-relacyjnych (Workbench( Workbench) 116 Utwórz nowy projekt i wybierz rodzaj źródła danych. File->New->Project...
Definiowanie odwzorowań obiektowo-relacyjnych (Workbench( Workbench) 117 Określ parametry fizycznego połączenia z bazą danych. Database->Add...
Definiowanie odwzorowań obiektowo-relacyjnych (Workbench( Workbench) 118 Określ lokalizację skompilowanych klas Java, które zostaną odwzorowane na tabele bazy danych. Project->General->Classpath
Definiowanie odwzorowań obiektowo-relacyjnych (Workbench( Workbench) 119 Załaduj definicje klas, które zostaną odwzorowane na tabele bazy danych. Project->Add or Refresh Classess...
Definiowanie odwzorowań obiektowo-relacyjnych (Workbench( Workbench) 120 Połącz się z bazą danych, załaduj definicje tabel. Database->Log In to Database Database->Add or Update Existing Tables from Database
Definiowanie odwzorowań obiektowo-relacyjnych (Workbench( Workbench) 121 Zdefiniuj odwzorowania klas i ich atrybutów na tabele i ich kolumny.
Definiowanie odwzorowań obiektowo-relacyjnych (Workbench( Workbench) 122 Zapisz plik projektu TopLink w formie pliku XML lub klasy Java. Export->Project Deployment XML... Export->Project Java Source...
Wykorzystanie gotowego projektu TopLink w JDeveloper 10g (XML) 123 Project project = XMLProjectReader.read("C:/MyApp1/MyProject1.xml"); DatabaseSession session = project.createdatabasesession(); DatabaseLogin login = new DatabaseLogin(); login.useplatform(new oracle.toplink.platform.database.oracle.oracle10platform()); login.setdriverclassname("oracle.jdbc.driver.oracledriver"); login.setconnectionstring("jdbc:oracle:thin:@localhost:1521:orcl"); login.setusername("scott"); login.setpassword("tiger"); session.setdatasourcelogin(login); session.login();...
Wykorzystanie gotowego projektu TopLink w JDeveloper 10g (Java) 124 Project project = new MyProject1(); DatabaseSession session = project.createdatabasesession(); DatabaseLogin login = new DatabaseLogin(); login.useplatform(new oracle.toplink.platform.database.oracle.oracle10platform()); login.setdriverclassname("oracle.jdbc.driver.oracledriver"); login.setconnectionstring("jdbc:oracle:thin:@localhost:1521:orcl"); login.setusername("scott"); login.setpassword("tiger"); session.setdatasourcelogin(login); session.login();...
125 Definiowanie odwzorowań obiektowo-relacyjnych za pomocą narzędzia JDeveloper 10g
Definiowanie odwzorowań obiektowo-relacyjnych (JDeveloper( 10g) Utwórz klasy Java, które zostaną odwzorowane na tabele bazy danych. 126 File->New...->General->Java Class
Definiowanie odwzorowań obiektowo-relacyjnych (JDeveloper( 10g) Określ parametry fizycznego połączenia z bazą danych. 127 Connections->Databae->New Database Connection...
Definiowanie odwzorowań obiektowo-relacyjnych (JDeveloper( 10g) Załaduj definicje tabel z bazy danych. 128 File->New...->Database Tier->Offline Database Objects Imported from Database
Definiowanie odwzorowań obiektowo-relacyjnych (JDeveloper( 10g) Utwórz plik projektu TopLink. 129 File->New...->Business Tier->TopLink Object-Relational Map
Definiowanie odwzorowań obiektowo-relacyjnych (JDeveloper( 10g) 130 Utwórz puste deskryptory dla klas Java, które będą odwzorowane na tabele bazy danych. Toplink->Add or Remove Descriptors...
Definiowanie odwzorowań obiektowo-relacyjnych (JDeveloper( 10g) 131 Zdefiniuj odwzorowania klas i ich atrybutów na tabele i ich kolumny.
Wykorzystanie projektu TopLink w JDeveloper 10g (XML) 132 public static final void main(string[] args) { Project project = XMLProjectReader.read( "META-INF/MyToplink1.xml", Thread.currentThread().getContextClassLoader()); DatabaseSession session = project.createdatabasesession(); session.shouldlogmessages(); session.login(); Collection results = session.readallobjects(dept.class); for (Iterator itr = results.iterator();itr.hasnext();) { printobjectattributes(itr.next(), session); } session.logout(); Wygeneruj kod przykładowej aplikacji-klienta. New Sample Java Client...
133 TopLink: : wybrane metody odwzorowania obiektowo-relacyjnego
Rodzaje odwzorowań 134 Odwzorowania bezpośrednie (direct mapping) dotyczą odwzorowania pojedynczego atrybutu na pojedynczą kolumnę tabeli Odwzorowania związków (relationship mapping) dotyczą odwzorowania powiązań pomiędzy obiektami na powiązania klucza obcego pomiędzy rekordami tabeli
Rodzaje odwzorowań bezpośrednich 135 Direct-to-field wartość atrybutu obiektu odpowiada wartości kolumny tabeli żadnych przekształceń Object type każdej wartości atrybutu obiektu odpowiada powiązana z nią wartość kolumny tabeli np. "Male" -> "M", "Female"->"F" Type conversion konwersja typu danych podczas odwzorowywania wartości atrybutu na wartość kolumny tabeli np. String->NUMBER Serialized Object wartość atrybutu obiektu jest serializowana i zapisywana w bazie danych jako BLOB
Rodzaje odwzorowań związk zków 136 One-to-one odwzorowuje powiązanie pojedynczego obiektu z innym pojedynczym obiektem np. samochód - dowód rejestracyjny Aggregate szczególny rodzaj związku one-to-one powiązane ze sobą kolumny stanowią jeden rekord One-to-many odwzorowuje powiązanie pojedynczego obiektu z wieloma obiektami np. departament - pracownicy Many-to-many odwzorowuje powiązanie wielu obiektów z wieloma obiektami np. pracownicy - projekty
Przykład definicji odwzorowania bezpośredniego 137 Powiąż deskryptor z tabelą Wybierz typ odwzorowania dla atrybutu: direct-to-field Powiąż atrybut z kolumną tabeli
Przykład definicji odwzorowania związku zku 1:N (1/2) Wybierz typ odwzorowania dla atrybutu: one-to-many 138 Wskaż deskryptor, do którego prowadzi referencja (strona "many") Wskaż powiązanie klucza obcego pomiędzy rekordami tabel bazy danych
Przykład definicji odwzorowania związku zku 1:N (2/2) 139 Zdefiniuj zwrotne powiązanie one-to-one
Przykład definicji odwzorowania związku zku M:N (1/2) 140 Wybierz typ odwzorowania dla atrybutu: many-to-many Wskaż deskryptor, do którego prowadzi referencja (druga strona "many") Wskaż tabelę implementującą związek M:N
Przykład definicji odwzorowania związku zku M:N (2/2) 141 Wskaż klucz obcy pomiędzy tabelą źródłową a tabelą implementującą związek M:N Wskaż klucz obcy pomiędzy tabelą implementującą związek M:N a tabelą docelową
Zarządzanie sesjami TopLink 142
Sesja TopLink 143 Sesja jest obiektem Java (interfejs Session), który reprezentuje połączenie aplikacji z relacyjną bazą danych, w pełni obsługując komunikację z serwerem bazy danych
Rodzaje sesji 144 DatabaseSession - uproszczona implementacja umożliwiająca pojedynczemu użytkownikowi dostęp do bazy danych Aplikacja ServerSession/ClientSession - umożliwia współbieżny dostęp do bazy danych przez wielu użytkowników, obsługuje buforowanie danych i grupowanie połączeń Aplikacja Aplikacja DatabaseSession ClientSession ClientSession ServerSession RemoteSession - umożliwia dostęp do bazy danych poprzez pośredniczący serwer TopLink
Tworzenie sesji DatabaseSession 145 Project Projekt TopLink (XML) XMLProjectReader.read("MyProject1") createdatabasesession() DatabaseSession login()
Tworzenie sesji DatabaseSession 146 Utworzenie sesji i połączenie się z bazą danych na podstawie parametrów zapisanych w pliku projektu: Project project = XMLProjectReader.read("C:/MyApp1/MyProject1.xml"); DatabaseSession session = project.createdatabasesession(); session.login();... session.logout(); Utworzenie sesji i połączenie się z bazą danych na podstawie parametrów podanych podczas działania aplikacji: Project project = XMLProjectReader.read("C:/MyApp1/MyProject1.xml"); DatabaseLogin login = project.getlogin(); login.setconnectionstring("jdbc:oracle:thin:@localhost:1521:orcl"); login.setusername("scott"); login.setpassword("tiger"); DatabaseSession session = project.createdatabasesession(); session.login();... session.logout();
Plik sessions.xml 147 <?xml version = '1.0' encoding = 'UTF-8'?> <!DOCTYPE toplink-configuration PUBLIC "-//Oracle Corp.//DTD TopLink Sessions 9.0.4//EN" "sessions_9_0_4.dtd"> <toplink-configuration> <session> <name>default</name> <project-xml>meta-inf/mytoplink1.xml</project-xml> <session-type> <server-session/> </session-type> <login> <driver-class>oracle.jdbc.oracledriver</driver-class> <connection-url>jdbc:oracle:thin:@localhost:1521:orcl</connection-url> <user-name>scott</user-name> <encrypted-password>3e20f8982c53f4aba825e30206ec8ade</encrypted-password> </login> </session> </toplink-configuration> Opcjonalny plik sessions.xml może być użyty do zapisu domyślnych parametrów połączeniowych
Wykorzystanie pliku sessions.xml 148 XMLSessionConfigLoader loader = new XMLSessionConfigLoader("C:/Myapp1/sessions.xml"); SessionManager mgr = SessionManager.getManager(); DatabaseSession session = (DatabaseSession)mgr.getSession(loader, "default", Thread.currentThread().getContextClassLoader()); Nazwa predefiniowanego połączenia z pliku sessions.xml
Tworzenie sesji ClientSession/ServerSession ServerSession 149 // inicjalizacja - utworzenie obiektu ServerSession Project project = XMLProjectReader.read("C:/MyApp1/MyProject1.xml"); ServerSession server = project.createserversession(1, 3); server.login(); // cykl pracy dla każdego klienta - utworzenie obiektu ClientSession ClientSession client = server.acquireclientsession();... client.release(); Minimalny/maksymalny rozmiar puli współdzielonych połączeń z bazą danych
Wykonywanie zapytań przez TopLink 150 Poprzez Session API: readobject() - odczyt pojedynczego odwzorowanego obiektu readallobjects() - odczyt wielu odwzorowanych obiektów executequery() - wykonanie dynamicznego zapytania Poprzez obiekty zapytań (query objects): ReadObjectQuery - odczyt pojedynczego odwzorowanego obiektu ReadAllQuery - odczyt wielu odwzorowanych obiektów Treść zapytania może być zdefiniowana z użyciem: języka wyrażeń obiektowych języka SQL języka EJB QL Query by Example
Wykonywanie zapytań przez TopLink 151 Odczytaj wszystkie odwzorowane obiekty klasy Emp: Vector results = session.readallobjects(emp.class); for (int i=0; i<results.size(); i++) { } Emp e = (Emp) results.elementat(i); System.out.println(e.getEname()); Odczytaj odwzorowane obiekty klasy Emp posługując się podanym zapytaniem SQL: ReadAllQuery query = new ReadAllQuery(); query.setreferenceclass(emp.class); query.setsqlstring("select * from emp where ename like 'K%'"); for (int i=0; i<results.size(); i++) { } Emp e = (Emp) results.elementat(i); System.out.println(e.getEname());
Wykonywanie zapytań przez TopLink 152 Odczytaj odwzorowane obiekty klasy Emp posługując się podanym zapytaniem EJB QL: ReadAllQuery query = new ReadAllQuery(); query.setreferenceclass(emp.class); query.setejbqlstring("select object(e) from Emp e where e.sal<3000"); for (int i=0; i<results.size(); i++) { Emp e = (Emp) results.elementat(i); System.out.println(e.getEname());} Odczytaj odwzorowane obiekty klasy Emp posługując się wyrażeniem obiektowym: ExpressionBuilder builder = new ExpressionBuilder(); Expression selectsalesmen = builder.get("job").equal("salesman"); Vector results = session.readallobjects(emp.class, selectsalesmen); for (int i=0; i<results.size(); i++) { Emp e = (Emp) results.elementat(i); System.out.println(e.getEname());}
Wykonywanie zapytań przez TopLink 153 Odczytaj odwzorowane obiekty klasy Emp posługując się zapytaniem Query-by-Example: Emp exampleemp = new Emp(); exampleemp.setename("martin"); exampleemp.setjob("salesman"); ReadAllQuery q = new ReadAllQuery(Emp.class); q.setexampleobject(exampleemp); Vector results = (Vector)session.executeQuery(q); for (int i=0; i<results.size(); i++) { } Emp e = (Emp) results.elementat(i); System.out.println(e.getSal());
Wykonywanie zapytań przez TopLink 154 Zdefiniuj treść zapytania w pliku projektu TopLink. Wykonaj sparametryzowane zapytanie predefiniowane: Vector results = (Vector)session.executeQuery("findRichEmp", Emp.class, 2500);
Zapytania dynamiczne 155
Wykonywanie zapytań dynamicznych 156 Treść zapytania może być konstruowana podczas działania aplikacji: w języku wyrażeń obiektowych w języku SQL poprzez wywołania funkcji składowanych w języku EJB QL metodą Query by Example
Język wyrażeń obiektowych 157 Obiekty klasy Expression reprezentują wyrażenia selekcji danych Do tworzenia obiektów Expression służy klasa ExpressionBuilder Klasa ExpressionMath implementuje operatory matematyczne do wykorzystania w wyrażeniach selekcji danych
Struktura prostych wyrażeń 158 zapis SQL np. upper(ename)='king' funkcja (atrybut) operator wartość get(atrybut).funkcja().operator(wartość) zapis wyrażenia obiektowego np. get("ename").touppercase().equal("king") w przypadku funkcji ExpressionMath: funkcja(get(atrybut)).operator(wartość)
Proste zapytania w języku j wyrażeń obiektowych 159 Pobierz dane pracowników spełniających warunek JOB='SALESMAN': ExpressionBuilder builder = new ExpressionBuilder(); Expression selectsalesmen = builder.get("job").equal("salesman"); Vector results = session.readallobjects(emp.class, selectsalesmen); for (int i=0; i<results.size(); i++) { Emp e = (Emp) results.elementat(i); System.out.println(e.getEname()); }
Proste zapytania w języku j wyrażeń obiektowych 160 Pobierz dane pracowników zatrudnionych w departamencie spełniającym warunek DEPTNO=20 Expression selectdept20 = builder.get("dept").get("deptno").equal(20); Metody pokrewne: - notequal(object) - greaterthan(object) - greaterthanequal(object) - lessthan(object) - lessthanequal(object) - isnull() - notnull() - between(value, value) - notbetween(value, value) - like(string) - notlike(string) - likeignorecase(string) - equalsignorecase(string) - containsallkeywords(string) - containsanykeywords(string) - in(values[]) - notin(values[]) - containssubstring(string)
Proste zapytania w języku j wyrażeń obiektowych 161 Pobierz dane pracowników spełniających warunek UPPER(ENAME) LIKE 'K%' Expression selectknames = builder.get("ename").touppercase().like("k%"); Metody pokrewne: - tolowercase() - touppercasecasedwords() - todate() - rightpad(int, String) - leftpad(int, String) - righttrim() - lefttrim() - trim() - length() - concat(object) - adddate(string, int) - addmonths(int) - monthsbetween(date) - nextday(string) - datedifference(string, Date) - datetostring() - indexof(string) - replace(string, String) - substring(int, int)
Proste zapytania w języku j wyrażeń obiektowych 162 Pobierz dane pracowników spełniających warunek JOB='SALESMAN' i zarazem zatrudnionych w departamencie spełniającym warunek DEPTNO=20 Expression selectsalesmen = builder.get("job").equal("salesman"); Expression selectdept20 = builder.get("dept").get("deptno").equal(20); Expression complexselect = selectdept20.and(selectsalesmen); Metody pokrewne: - or(expression) - not()
Proste zapytania w języku j wyrażeń obiektowych - ExpressionMath 163 Pobierz dane pracowników, których pensja powiększona o 40% przekracza $6000 Expression selectsalesmen = ExpressionMath.multiply(builder.get("sal"), 1.4).greaterThan(6000); Metody pokrewne: - add(expression, Object) - ceil(expression) - sin(expression) - cos(expression) - divide(expression, Object) - floor(expression) - log(expression) - mod(expression, int) - multiply(expression, Object) - power(expression,object) - round(expression, int) - subtract(expression, Object) - tan(expression) - trunc(expression, int)
Obsługa tożsamo samości obiektów 164
Tożsamo samość obiektów: motywacje 165 TopLink wymaga implementacji (wskazania) atrybutów reprezentujących wartości klucza podstawowego odwzorowywanej tabeli Obiekt o danej wartości klucza podstawowego występuje w pamięci operacyjnej wyłącznie raz
Generowanie wartości kluczy 166 Podczas wprowadzania danych TopLink może generować wartości kluczy podstawowych: za pomocą tabeli sekwekcji za pomocą rodzimych mechanizmów oferowanych przez system zarządzania bazą danych Tabela sekwencji: dwie kolumny: nazwa sekwencji i aktualna wartość sekwencji tworzona przez programistę wskazana do użycia przez TopLink
Bufor obiektów 167 W celu poprawy wydajności, TopLink przechowuje w pamięci operacyjnej ostatnio odczytywane obiekty odwzorowujące dane z bazy danych Mapa tożsamościowa (identity map) - struktura danych składająca się z wartości kluczy podstawowych i skojarzonych z nimi obiektów Session 1 2 3 N Identity Map (Emp):... 10 20 Identity Map (Dept):...
Parametry bufora obiektów 168 Algorytm obsługi bufora: Weak with Soft Subcache: pierwszych n obiektów powiązanych referencjami soft, pozostałe referencjami weak (zalecany) Weak with Hard Subcache: pierwszych n obiektów powiązanych referencjami harf, pozostałe referencjami weak Weak: wszystkie obiekty powiązane referencjami weak Full: wszystkie obiekty przechowywane na stałe None: brak bufora Rozmiar bufora
Przetwarzanie transakcyjne 169
Unit of Work 170 Mechanizm Unit of Work umożliwia realizację transakcji na poziomie modelu obiektowego oraz jej odwzorowanie na transakcję w bazie danych Jeżeli podczas Unit of Work wystąpi błąd: zmiany w bazie danych są wycofywane przywracany jest poprzedni stan obiektów w pamięci operacyjnej Podczas realizacji operacji zatwierdzenia Unit of Work: rozpoczynana jest transakcja w bazie danych wykonywane są modyfikacje tylko tych danych, które zostały zmienione przez użytkownika zatwierdzana jest transakcja w bazie danych Unit of Work wymaga, aby wszystkie operacje modyfikacji danych były wykonywane z użyciem "kopii roboczej" właściwego obiektu
Implementacja transakcji Unit of Work 171 Pobierz obiekt transakcji UnitOfWork uow = session.acquireunitofwork(); Zarejestruj obiekt, który zamierzasz modyfikować - w odpowiedzi otrzymasz "kopię roboczą" Emp employeecopy = (Emp) uow.registerobject(employee); Przeprowadź modyfikację danych korzystając z kopii roboczej obiektu employeecopy.setename("kowalski"); Zatwierdź transakcję uow.commit();
Funkcjonalność Unit of Work 172 register(object) - dokonuje rejestracji podanego obiektu; zwraca kopię roboczą registerallobjects(vector) - dokonuje rejestracji wszystkich obiektów umieszczonych w tablicy; zwraca tablicę kopii roboczych commit() - zatwierdza transakcję, dezaktualizuje kopie robocze commitandresume() - zatwierdza transakcję, kopie robocze mogą być nadal wykorzystywane revertobject(object) - wycofuje transakcję, przywraca obiektom stan sprzed rozpoczęcia transakcji, kopie robocze pozostają ważne revertandresume() - przywraca obiektom stan sprzed rozpoczęcia transakcji lecz nie wycofuje transakcji