16 Haziran 2020 Salı

SpringData @Transactional Anotasyonu Propagation Değerleri

Giriş
Bu alan şu değerleri alabiliyor
REQUIRED
REQUIRES_NEW
NESTED
MANDATORY
NEVER
NOT_SUPPORTED
SUPPORTS
REQUIRED
Eğer başlatılmış transaction yoksa yeni bir tane yaratır. Eğer varsa mevcut transaction'a kullanılır.

REQUIRES_NEW
Her zaman yeni bir transaction yaratır deniliyor, ancak şu açıklamaya dikkat etmek lazım
Often people think of this propagation setting as “magically tells the database to make a nested transaction”. However this mental model is wrong — many Databases don’t even have nested transactions, so something else needs to happen.

What actually happens is that Spring will open a new connection to the database.
Örnek
Şöyle yaparız.
@Service
@Transactional
public class FooService implements Foo {

  @Transactional(propagation = Propagation.REQUIRES_NEW)
  public void processEachCustomer(Customer customer){
    ...
  }
}
NESTED
Başlatılmış transacion yoksa yeni bir tane başlatır, eğer varsa Savepoint kullanır. Açıklaması şöyle. Her JPA sağlayıcısı bu özelliği desteklemiyor.
NESTED acts like REQUIRED, only it uses savepoints between nested invocations. In other words, inner logical transactions may roll back independently of outer logical transactions.
Açıklaması şöyle.
For NESTED propagation, Spring checks if a transaction exists, then if yes, it marks a savepoint. This means if our business logic execution throws an exception, then transaction rollbacks to this savepoint. If there's no active transaction, it works like REQUIRED.
Açıklaması şöyle
DataSourceTransactionManager supports this propagation out-of-the-box. Also, some implementations of JTATransactionManager may support this.

JpaTransactionManager supports NESTED only for JDBC connections. However, if we set nestedTransactionAllowed flag to true, it also works for JDBC access code in JPA transactions if our JDBC driver supports savepoints.
Hibernate ile şu hatayı alırız
NestedTransactionNotSupportedException: JpaDialect does not support savepoints check your JPA provider capabilities
MANDATORY
Başlatılmış bir transaction yok ise exception fırlatır.
Örnek
Şöyle yaparız.
@Transactional(propagation = Propagation.MANDATORY)
NEVER
Başlatılmış bir transaction olmaması gerekir. Açıklaması şöyle.
The Propagation.NEVER states that no physical transaction should exist. If a physical transaction is found, then NEVER will cause an exception as follows:

org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation 'never'
NOT_SUPPORTED
Metod çalışır ancak başlatılmış bir transaction varsa ona dahil olmaz. Açıklaması şöyle.
Propagation.NOT_SUPPORTED states that if a physical transaction exists, then it will be suspended before continuing. This physical transaction will be automatically resumed at the end. After this transaction is resumed, it can be rolled back (in case of a failure) or committed.
NOt_SUPPORTED performansı artırabilir. Açıklaması şöyle
If there is any active Transaction, it is suspended and the service method is executed without Transaction. After the method has been completed, the container resumes the client’s transaction.
It is recommended to use the NotSupported attribute for methods that don’t need transactions. Because transactions involve overhead, this attribute may improve performance.
SUPPORTS
Açıklaması şöyle. Başlatılmış bir transaction varsa kullanır, yoksa transaction başlatmaz.
For SUPPORTS, Spring first checks if an active transaction exists. If a transaction exists, then the existing transaction will be used. If there isn't a transaction, it is executed non-transactional:

Hiç yorum yok:

Yorum Gönder