Spring @Transactional-izolacja, rozmnażanie

Czy ktoś może wyjaśnić co izolacja & parametry propagacji {[3] } są dla w adnotacji @Transactional na przykładzie świata rzeczywistego. Zasadniczo kiedy i dlaczego powinienem wybrać zmianę ich wartości domyślnych.

Author: Bhesh Gurung, 2011-12-13

10 answers

Dobre pytanie, choć nie trywialne do odpowiedzi.

Rozmnażanie

Określa, w jaki sposób transakcje odnoszą się do siebie. Opcje wspólne

  • Required: kod będzie zawsze uruchamiany w transakcji. Utwórz nową transakcję lub użyj ponownie, jeśli jest dostępna.
  • Requires_new: Kod będzie zawsze uruchamiany w nowej transakcji. Zawiesić bieżącą transakcję, jeśli taka istnieje.

Izolacja

Definiuje umowę danych pomiędzy transakcje.

  • Read Uncommitted: pozwala na brudne odczyty
  • Read Committed: nie pozwala na brudne odczyty
  • Repeatable Read: jeśli wiersz zostanie odczytany dwa razy w tym samym transakcjonie, wynik będzie zawsze taki sam
  • Serializable: wykonuje wszystkie transakcje w sekwencji

Różne poziomy mają różne charakterystyki wydajności w aplikacji wielowątkowej. Myślę, że jeśli zrozumiesz koncepcję dirty reads, będziesz mógł wybrać dobrą opcję.


Przykład kiedy może wystąpić brudny odczyt

  thread 1   thread 2      
      |         |
    write(x)    |
      |         |
      |        read(x)
      |         |
    rollback    |
      v         v 
           value (x) is now dirty (incorrect)

Tak więc rozsądną wartością domyślną (jeśli można ją żądać) może być Read Comitted, która pozwala tylko odczytywać wartości, które zostały już przekazane przez inne uruchomione transakcje, w połączeniu z poziomem propagacji Required. Następnie możesz pracować stamtąd, jeśli aplikacja ma inne potrzeby.


Praktyczny przykład, w którym nowa transakcja będzie zawsze tworzona podczas wprowadzania procedury provideService i zakończona po wyjściu.

public class FooService {
    private Repository repo1;
    private Repository repo2;

    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public void provideService() {
        repo1.retrieveFoo();
        repo2.retrieveFoo();
    }
}

Had we użyty Required zamiast tego transakcja pozostanie otwarta, jeśli transakcja była już otwarta podczas wprowadzania procedury. Należy również zauważyć, że wynik rollback Może być inny, ponieważ kilka egzekucji może wziąć udział w tej samej transakcji.


Możemy łatwo zweryfikować zachowanie za pomocą testu i zobaczyć, jak wyniki różnią się od poziomów propagacji

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:/fooService.xml")
public class FooServiceTests {

    private @Autowired TransactionManager transactionManager;
    private @Autowired FooService fooService;

    @Test
    public void testProvideService() {
        TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
        fooService.provideService();
        transactionManager.rollback(status);
        // assert repository values are unchanged ... 
}

O poziomie propagacji

  • Requires new spodziewalibyśmy się fooService.provideService() byłNie zwinięty od czasu utworzenia własnej sub-transakcji.

  • Required spodziewalibyśmy się, że wszystko zostanie wycofane i zaplecze sklepu bez zmian.

 299
Author: Johan Sjöberg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:37

PROPAGATION_REQUIRED = 0; Jeśli DataSourceTransactionObject T1 jest już uruchomiony dla metody M1.Jeśli dla innej metody m2 jest wymagany obiekt transakcji ,nie zostanie utworzony nowy obiekt transakcji .Ten sam obiekt T1 jest używany dla M2

PROPAGATION_MANDATORY = 2 ; Metoda musi działać w ramach transakcji. Jeśli nie istniejąca transakcja jest w toku, wyjątek zostanie wyrzucony

PROPAGATION_REQUIRES_NEW = 3; Jeśli DataSourceTransactionObject T1 jest już uruchomiony dla metody M1 i jest w trakcie (wykonanie metody M1).Jeżeli inna metoda m2 rozpocznie wykonywanie, to T1 zostanie zawieszone na czas trwania metody m2 z nowym DataSourceTransactionObject T2 dla M2.M2 działa w ramach własnego kontekstu transakcyjnego

PROPAGATION_NOT_SUPPORTED = 4 ; Jeśli DataSourceTransactionObject T1 jest już uruchomiony dla metody M1.Jeśli inna metoda M2 jest uruchamiana jednocześnie .Wtedy M2 nie powinien działać w kontekście transakcji. T1 jest zawieszony do M2 jest skończone.

PROPAGATION_NEVER = 5 ; żadna z metod nie działa w kontekście transakcji.

Stopień izolacji: Chodzi o to, jak duży wpływ na transakcję mogą mieć działania innych współbieżnych transactions.It a obsługuje spójność, pozostawiając dane w wielu tabelach w spójnym stanie. Polega na blokowaniu wierszy i / lub tabel w bazie danych.

Problem z wieloma transakcjami

Scenariusz 1 .Jeżeli transakcja T1 odczytuje dane z tabeli A1, które zostały zapisane przez inną równoległą transakcję T2.Jeśli po drodze T2 jest rollback, dane uzyskane przez T1 jest nieważny.Np. g a = 2 jest danymi oryginalnymi .If T1 read a=1 that was written by T2.Jeśli T2 rollback to a=1 będzie rollback do a = 2 w DB.Ale teraz T1 ma a=1 ale w DB tabela zostanie zmieniona na a=2.

Scenario2 .Jeżeli transakcja T1 odczytuje dane z tabeli A1.Jeżeli Inna równoległa transakcja (T2) zaktualizuje dane w tabeli A1.Wtedy dane odczytane przez T1 są inne niż w tabeli A1.Ponieważ T2 zaktualizował dane z tabeli A1.Np. jeśli T1 odczyt a = 1 i T2 zaktualizowany a = 2.Potem a!=B.

Scenariusz 3 .Jeżeli transakcja T1 odczytuje dane z tabeli A1 z określoną liczbą wierszy. Jeśli inna równoległa transakcja (T2) wstawia więcej wierszy w tabeli A1.Na liczba wierszy odczytanych przez T1 różni się od wierszy w tabeli A1

Scenariusz 1 nazywa się Dirty reads.

Scenariusz 2 nazywa się odczytami Nie powtarzalnymi.

Scenariusz 3 nazywa się widmo czyta.

Tak więc poziom izolacji jest rozszerzeniem, któremu można zapobiec scenariuszowi 1, scenariuszowi 2, scenariuszowi 3 . Możesz uzyskać pełny poziom izolacji, wdrażając blokowanie.To uniemożliwia równoczesne odczyty i zapisuje do tych samych danych z tego samego miejsca.Ale to wpływa na wydajność .Poziom izolacji zależy od zastosowania do zastosowania, ile izolacji jest wymagane.

ISOLATION_READ_UNCOMMITTED : pozwala odczytać zmiany, które haven ' t yet been committed.It suffer from Scenario 1, Scenario 2, Scenario 3

ISOLATION_READ_COMMITTED : umożliwia odczyt z jednoczesnych transakcji, które zostały zatwierdzone. Może cierpieć na scenariusz 2 i scenariusz 3. Ponieważ inne transakcje mogą aktualizować dane.

ISOLATION_REPEATABLE_READ: wielokrotne odczyty tego samego pola przyniosą te same wyniki, dopóki nie zostanie ono zmienione przez itself.It może cierpieć na scenariusz 3.Ponieważ inne transakcje mogą być wstawianie danych

ISOLATION_SERIALIZABLE : scenariusz 1, Scenariusz 2, scenariusz 3 nigdy happens.It jest kompletna isolation.It obejmuje pełne locking.It affets performace ze względu na zamykam.

Możesz przetestować za pomocą

public class TransactionBehaviour {
   // set is either using xml Or annotation
    DataSourceTransactionManager manager=new DataSourceTransactionManager();
    SimpleTransactionStatus status=new SimpleTransactionStatus();
   ;


    public void beginTransaction()
    {
        DefaultTransactionDefinition Def = new DefaultTransactionDefinition();
        // overwrite default PROPAGATION_REQUIRED and ISOLATION_DEFAULT
        // set is either using xml Or annotation
        manager.setPropagationBehavior(XX);
        manager.setIsolationLevelName(XX);

        status = manager.getTransaction(Def);

    }

    public void commitTransaction()
    {


            if(status.isCompleted()){
                manager.commit(status);
        } 
    }

    public void rollbackTransaction()
    {

            if(!status.isCompleted()){
                manager.rollback(status);
        }
    }
    Main method{
        beginTransaction()
        M1();
        If error(){
            rollbackTransaction()
        }
         commitTransaction();
    }

}

Możesz debugować i zobaczyć wynik z różnymi wartościami dla izolacji i propagacji.

 203
Author: abishkar bhattarai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-15 12:53:52

Wystarczające wyjaśnienie każdego parametru jest podane przez inne odpowiedzi; jakkolwiek poprosiłeś o przykład z prawdziwego świata, oto ten, który wyjaśnia cel różnych opcji propagacji :

Załóżmy, że jesteś odpowiedzialny za wdrożenie usługi rejestracji , w której e-mail z potwierdzeniem jest wysyłany do użytkownika. Pojawiają się dwa obiekty usługowe, jeden do zapisywania użytkownika i jeden do wysyłania e-maili, które to drugie jest wywoływane wewnątrz pierwszego. Na przykład coś takiego:
/* Sign Up service */
@Service
@Transactional(Propagation=REQUIRED)
class SignUpService{
 ...
 void SignUp(User user){
    ...
    emailService.sendMail(User);
 }
}

/* E-Mail Service */
@Service
@Transactional(Propagation=REQUIRES_NEW)
class EmailService{
 ...
 void sendMail(User user){
  try{
     ... // Trying to send the e-mail
  }catch( Exception)
 }
}

Być może zauważyłeś, że druga usługa jest typu propagacji REQUIRES_NEW , a ponadto jest szansa, że wyrzuci wyjątek(serwer SMTP wyłączony, nieprawidłowy e-mail lub inne powody).Prawdopodobnie nie chcesz, aby cały proces cofał się, jak usunięcie informacji o użytkowniku z bazy danych lub innych rzeczy; dlatego wywołujesz drugą usługę w oddzielnej transakcji.

Wracając do naszego przykładu, tym razem martwisz się o bazę danych bezpieczeństwo, więc definiujesz swoje klasy DAO w ten sposób:
/* User DAO */
@Transactional(Propagation=MANDATORY)
class UserDAO{
 // some CRUD methods
}

Oznacza to, że ilekroć tworzony jest obiekt DAO, a tym samym potencjalny dostęp do db, musimy zapewnić, że wywołanie zostało wykonane z wewnątrz jednej z naszych usług, co oznacza, że powinna istnieć transakcja na żywo; w przeciwnym razie występuje wyjątek.Dlatego propagacja jest typu obowiązkowa .

 73
Author: ye9ane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-01 12:58:26

Poziom izolacji określa, w jaki sposób zmiany wprowadzone do niektórych repozytoriów danych przez jedną transakcję wpływają na inne równoczesne transakcje, a także jak i kiedy te zmienione dane stają się dostępne dla innych transakcji. Kiedy definiujemy transakcję za pomocą frameworka Spring, jesteśmy również w stanie skonfigurować, na jakim poziomie izolacji ta sama transakcja będzie wykonywana.

@Transactional(isolation=Isolation.READ_COMMITTED)
public void someTransactionalMethod(Object obj) {

}

READ_UNCOMMITTED isolation level stwierdza, że transakcja może odczytywać dane, które są nadal niezatwierdzone przez inne transakcje.

READ_COMMITTED isolation level stwierdza, że transakcja nie może odczytać danych, które nie zostały jeszcze zatwierdzone przez inne transakcje.

REPEATABLE_READ isolation level stwierdza, że jeśli transakcja odczytuje jeden rekord z bazy danych wiele razy, wynik wszystkich tych operacji odczytu musi być zawsze taki sam.

SERIALIZOWALNY poziom izolacji jest najbardziej restrykcyjnym ze wszystkich poziomów izolacji. Transakcje są wykonywane z blokadą w ogóle poziomy (blokowanie odczytu, zakresu i zapisu) tak, aby wyglądały tak, jakby były wykonywane w sposób serializowany.

Propagacja to umiejętność decydowania o tym, w jaki sposób metody biznesowe powinny być zawarte zarówno w transakcjach logicznych, jak i fizycznych.

Spring wymagane zachowanie oznacza, że ta sama transakcja zostanie użyta, jeśli istnieje już otwarta transakcja w bieżącym kontekście wykonywania metody bean.

REQUIRES_NEW zachowanie oznacza, że nowa transakcja fizyczna będzie zawsze być tworzone przez kontener.

Zagnieżdżone zachowanie sprawia, że zagnieżdżone transakcje Spring używają tej samej fizycznej transakcji, ale ustawia punkty zapisu między zagnieżdżonymi wywołaniami, dzięki czemu transakcje wewnętrzne mogą również wycofywać się niezależnie od transakcji zewnętrznych.

Obowiązkowe zachowanie mówi, że istniejąca otwarta transakcja musi już istnieć. Jeśli nie wyjątek zostanie wyrzucony przez kontener.

Zachowanie nigdy mówi, że istniejąca otwarta transakcja nie może już istnieją. Jeśli transakcja istnieje, wyjątek zostanie wyrzucony przez kontener.

Zachowanie NOT_SUPPORTED wykona się poza zakresem jakiejkolwiek transakcji. Jeśli otwarta transakcja już istnieje, zostanie ona wstrzymana.

Zachowanie obsługi zostanie wykonane w zakresie transakcji, jeśli otwarta transakcja już istnieje. Jeśli nie istnieje już otwarta transakcja, metoda zostanie wykonana w sposób nietransakcyjny.

 40
Author: reos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-04 03:53:33

Prawie nigdy nie chcesz używać Read Uncommited, ponieważ nie jest to naprawdę ACID Zgodne. Read Commmited jest dobrym domyślnym miejscem startu. {[3] } jest prawdopodobnie potrzebny tylko w scenariuszach raportowania, rollup lub agregacji. Zauważ, że wiele DBs, w tym postgres, nie obsługuje powtarzalnego odczytu, musisz zamiast tego użyć Serializable. Serializable jest przydatny do rzeczy, o których wiesz, że muszą się wydarzyć zupełnie niezależnie od czegokolwiek innego; pomyśl o tym jak o synchronized w Javie. Serializable idzie w parze z REQUIRES_NEW rozmnażanie.

Używam REQUIRES dla wszystkich funkcji uruchamiających zapytania UPDATE lub DELETE oraz funkcji poziomu "service". Dla funkcji poziomu DAO, które uruchamiają tylko Selecty, używam SUPPORTS, która będzie uczestniczyć w TX, jeśli już jest uruchomiona(tzn. jest wywoływana z funkcji service).

 16
Author: AngerClown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-13 15:13:14

Izolacja transakcji i propagacja transakcji chociaż są ze sobą powiązane, ale są wyraźnie dwoma bardzo różnymi pojęciami. W obu przypadkach domyślne wartości są dostosowywane w komponencie boundary klienta za pomocą deklaratywnego zarządzania transakcjami lub Programowego zarządzania transakcjami. Szczegóły dotyczące poszczególnych poziomów izolacji i atrybutów propagacji można znaleźć w poniższych linkach referencyjnych.

Izolacja Transakcji

Dla dwóch lub więcej biegowych transakcje / połączenia z bazą danych, jak i kiedy zmiany wprowadzane przez zapytania w jednej transakcji wpływ / widoczne dla zapytań w innej transakcji. Dotyczyło to również tego, jakiego rodzaju blokowanie rekordów bazy danych będzie używane do izolowania zmian w tej transakcji od innych transakcji i vice versa. Jest to zazwyczaj realizowane przez bazę danych / zasób, który uczestniczy w transakcji.

.

Propagacja Transakcji

W aplikacji dla przedsiębiorstw dla każdego żądania / przetwarzania istnieje wiele komponentów, które są zaangażowane w wykonanie zadania. Niektóre z tych komponentów oznaczają granice (początek/koniec) transakcji, która będzie używana w danym komponencie i jego podskładnikach. Dla tej granicy transakcyjnej komponentów, Propogation transakcji określa, czy dany komponent będzie lub nie będzie uczestniczył w transakcji i co się stanie, jeśli wywołujący komponent już ma lub nie ma już utworzonej/rozpoczętej transakcji. To jest taki sam jak atrybuty transakcji Java EE. Zazwyczaj jest to realizowane przez menedżera transakcji/połączeń klienta.

Numer referencyjny:

 11
Author: Gladwin Burboz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-26 20:09:14

I have run outerMethod,method_1 i method_2 z innym trybem propagacji.

Poniżej znajduje się wyjście dla różnych trybów propagacji.

  • Metoda Zewnętrzna

    @Transactional
    @Override
    public void outerMethod() {
        customerProfileDAO.method_1();
        iWorkflowDetailDao.method_2();
    }
    
  • Method_1

    @Transactional(propagation=Propagation.MANDATORY)
    public void method_1() {
        Session session = null;
        try {
            session = getSession();
            Temp entity = new Temp(0l, "XXX");
            session.save(entity);
            System.out.println("Method - 1 Id "+entity.getId());
        } finally {
            if (session != null && session.isOpen()) {
            }
        }
    }
    
  • Method_2

    @Transactional()
    @Override
    public void method_2() {
        Session session = null;
        try {
            session = getSession();
            Temp entity = new Temp(0l, "CCC");
            session.save(entity);
            int i = 1/0;
            System.out.println("Method - 2 Id "+entity.getId());
        } finally {
            if (session != null && session.isOpen()) {
            }
        }
    }
    
      • outerMethod-bez transakcji
      • metoda_1-propagacja.Obowiązkowe) -
      • method_2-tylko adnotacja do transakcji
      • wyjście: formula_1 wyrzuci wyjątek, którego nie ma transakcja
      • outerMethod-bez transakcji
      • method_1 - tylko adnotacja do transakcji
      • metoda_2-propagacja.Obowiązkowe)
      • wyjście: metoda_2 wyrzuci wyjątek, że żadna transakcja nie istnieje
      • Output: method_1 będzie utrzymywać rekord w bazie danych.
      • outerMethod - z transakcją
      • method_1 - tylko adnotacja do transakcji
      • metoda_2-propagacja.Obowiązkowe)
      • wyjście: method_2 będzie utrzymywać rekord w bazie danych.
      • Output: method_1 będzie utrzymywać rekord w bazie danych. -- Tutaj główna zewnętrzna transakcja używana zarówno dla metody 1, jak i 2
      • outerMethod - z transakcją
      • metoda_1-propagacja.Obowiązkowe) -
      • method_2 - tylko adnotacja transakcji i wyrzuca wyjątek
      • wyjście: brak zapisu w bazie oznacza cofnięcie załatwione.
      • outerMethod - z transakcją
      • metoda_1-propagacja.REQUIERES_NEW)
      • metoda_2-propagacja.REQUIERES_NEW) i wyrzuca wyjątek 1/0
      • Output: method_2 wyrzuci wyjątek, więc rekord method_2 nie został utrzymany.
      • Output: method_1 będzie utrzymywać rekord w bazie danych.
      • Wyjście: nie ma cofnięcia dla metody_1
 6
Author: NIrav Modi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-26 10:04:19

Możemy dodać do tego:

@Transactional(readOnly = true)
public class Banking_CustomerService implements CustomerService {

    public Customer getDetail(String customername) {
        // do something
    }

    // these settings have precedence for this method
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public void updateCustomer(Customer customer) {
        // do something
    }
}
 3
Author: Ankit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-06 14:06:10

Transakcja reprezentuje jednostkę pracy z bazą danych.

W interfejsie spring TransactionDefinition definiującym właściwości transakcji zgodne z Spring. @Transactional adnotacja opisuje atrybuty transakcji w metodzie lub klasie.

@Autowired
private TestDAO testDAO;

@Transactional(propagation=TransactionDefinition.PROPAGATION_REQUIRED,isolation=TransactionDefinition.ISOLATION_READ_UNCOMMITTED)
public void someTransactionalMethod(User user) {

  // Interact with testDAO

}

Rozmnażanie (rozmnażanie): jest wykorzystywane do relacji między transakcjami. (analogicznie do java inter thread communication)

+-------+---------------------------+------------------------------------------------------------------------------------------------------+
| value |        Propagation        |                                             Description                                              |
+-------+---------------------------+------------------------------------------------------------------------------------------------------+
|    -1 | TIMEOUT_DEFAULT           | Use the default timeout of the underlying transaction system, or none if timeouts are not supported. |
|     0 | PROPAGATION_REQUIRED      | Support a current transaction; create a new one if none exists.                                      |
|     1 | PROPAGATION_SUPPORTS      | Support a current transaction; execute non-transactionally if none exists.                           |
|     2 | PROPAGATION_MANDATORY     | Support a current transaction; throw an exception if no current transaction exists.                  |
|     3 | PROPAGATION_REQUIRES_NEW  | Create a new transaction, suspending the current transaction if one exists.                          |
|     4 | PROPAGATION_NOT_SUPPORTED | Do not support a current transaction; rather always execute non-transactionally.                     |
|     5 | PROPAGATION_NEVER         | Do not support a current transaction; throw an exception if a current transaction exists.            |
|     6 | PROPAGATION_NESTED        | Execute within a nested transaction if a current transaction exists.                                 |
+-------+---------------------------+------------------------------------------------------------------------------------------------------+

Izolacja: izolacja jest jednym z kwasów (Atomiczność, spójność, Izolacja, trwałość) właściwości transakcji baz danych. Izolacja określa, w jaki sposób integralność transakcji jest widoczna dla innych użytkowników i systemów. Używa do blokowania zasobów tj. kontroli współbieżności, upewnij się, że tylko jedna transakcja może uzyskać dostęp do zasobu w danym punkcie.

Blokowanie percepcji: poziom izolacji określa czas trwania blokady.

+---------------------------+-------------------+-------------+-------------+------------------------+
| Isolation Level Mode      |  Read             |   Insert    |   Update    |       Lock Scope       |
+---------------------------+-------------------+-------------+-------------+------------------------+
| READ_UNCOMMITTED          |  uncommitted data | Allowed     | Allowed     | No Lock                |
| READ_COMMITTED (Default)  |   committed data  | Allowed     | Allowed     | Lock on Committed data |
| REPEATABLE_READ           |   committed data  | Allowed     | Not Allowed | Lock on block of table |
| SERIALIZABLE              |   committed data  | Not Allowed | Not Allowed | Lock on full table     |
+---------------------------+-------------------+-------------+-------------+------------------------+

Czytaj: następujące 3 rodzaje głównych problemy występują:

  • Dirty reads : odczytuje niezakontraktowane dane z innego tx(transakcji).
  • odczyty powtarzalne : odczyty popełnione UPDATES z innego tx.
  • Phantom czyta : czyta popełnione INSERTS i/lub DELETES z innego tx

Poziomy izolacji z różnymi rodzajami odczytów:

+---------------------------+----------------+----------------------+----------------+
| Isolation Level Mode      |  Dirty reads   | Non-repeatable reads | Phantoms reads |
+---------------------------+----------------+----------------------+----------------+
| READ_UNCOMMITTED          | allows         | allows               | allows         |
| READ_COMMITTED (Default)  | prevents       | allows               | allows         |
| REPEATABLE_READ           | prevents       | prevents             | allows         |
| SERIALIZABLE              | prevents       | prevents             | prevents       |
+---------------------------+----------------+----------------------+----------------+

Na przykład

 3
Author: Premraj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-19 02:06:53

Możesz użyć TAK:

@Transactional(propagation = Propagation.REQUIRES_NEW)
public EventMessage<ModificaOperativitaRapporto> activate(EventMessage<ModificaOperativitaRapporto> eventMessage) {
//here some transaction related code
}

Możesz też użyć tej rzeczy:

public interface TransactionStatus extends SavepointManager {
    boolean isNewTransaction();
    boolean hasSavepoint();
    void setRollbackOnly();
    boolean isRollbackOnly();
    void flush();
    boolean isCompleted();
}
 1
Author: Ankit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-06 13:58:16