Spring @Transactional - isolasi, propagasi

447

Adakah yang bisa menjelaskan parameter isolasi & propagasi apa untuk @Transactionalanotasi melalui contoh dunia nyata?

Pada dasarnya kapan dan mengapa saya harus memilih untuk mengubah nilai standarnya.

Mat B.
sumber

Jawaban:

442

Pertanyaan bagus, meski bukan hal yang sepele untuk dijawab.

Perambatan

Menentukan bagaimana transaksi saling berhubungan. Opsi umum:

  • Required: Kode akan selalu berjalan dalam transaksi. Membuat transaksi baru atau menggunakan kembali jika tersedia.
  • Requires_new: Kode akan selalu berjalan dalam transaksi baru. Tangguhkan transaksi saat ini jika ada.

Isolasi

Menentukan kontrak data antar transaksi.

  • Read Uncommitted: Memungkinkan pembacaan kotor.
  • Read Committed: Tidak mengizinkan pembacaan kotor.
  • Repeatable Read: Jika satu baris dibaca dua kali dalam transaksi yang sama, hasilnya akan selalu sama.
  • Serializable: Melakukan semua transaksi secara berurutan.

Level yang berbeda memiliki karakteristik kinerja yang berbeda dalam aplikasi multi-threaded. Saya pikir jika Anda memahami dirty readskonsepnya, Anda akan dapat memilih opsi yang baik.


Contoh kapan pembacaan kotor dapat terjadi:

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

Jadi default waras (jika dapat diklaim) bisa Read Committed, yang hanya memungkinkan Anda membaca nilai yang telah dilakukan oleh transaksi berjalan lainnya, dalam kombinasi dengan tingkat propagasi Required. Maka Anda dapat bekerja dari sana jika aplikasi Anda memiliki kebutuhan lain.


Contoh praktis tentang di mana transaksi baru akan selalu dibuat saat memasuki provideServicerutinitas dan selesai saat meninggalkan:

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

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

Kalau saja kita menggunakan Required, transaksi akan tetap terbuka jika transaksi sudah terbuka ketika memasuki rutin. Perhatikan juga bahwa hasil dari a rollbackdapat berbeda karena beberapa eksekusi dapat mengambil bagian dalam transaksi yang sama.


Kami dapat dengan mudah memverifikasi perilaku dengan tes dan melihat bagaimana hasilnya berbeda dengan tingkat propagasi:

@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 ... 
}

Dengan tingkat propagasi

  • Requires new: Kita harapkan fooService.provideService()itu tidak digulung kembali karena dibuat itu sendiri sub-transaksi.

  • Required: kami harapkan semuanya dibatalkan dan toko dukungan tidak berubah.

Johan Sjöberg
sumber
Bagaimana tautan terakhir itu terkait dengan apa yang Anda bicarakan? Menurut dokumen yang ditautkan, itu adalah sesi yang tampaknya menyatakan apa transaksi saat ini, bukan pabrik sesi.
Donal Fellows
@ Donal, oh maaf itu tidak jelas. Maksud saya adalah, sejak sessionFactory.getCurrentTransaction()ditambahkan tidak perlu berjalan HibernateTemplatelagi untuk mengelola transaksi. Saya menghapusnya :)
Johan Sjöberg
Pertanyaan saya adalah tentang di mana tautan menunjuk, sungguh. :-)
Donal Fellows
cara mendapatkan perubahan yang dibuat dalam transaksi saat ini- stackoverflow.com/questions/36132667/...
Prasanna Kumar HA
304

PROPAGATION_REQUIRED = 0 ; Jika DataSourceTransactionObject T1 sudah dimulai untuk Metode M1.Jika untuk Metode lain objek Transaksi M2 diperlukan, tidak ada objek Transaksi baru dibuat. Objek yang sama T1 digunakan untuk M2

PROPAGATION_MANDATORY = 2 ; Metode harus dijalankan dalam suatu transaksi. Jika tidak ada transaksi yang sedang berlangsung, pengecualian akan dilemparkan

PROPAGATION_REQUIRES_NEW = 3 ; Jika DataSourceTransactionObject T1 sudah dimulai untuk Metode M1 dan sedang dalam proses (mengeksekusi metode M1). Jika metode lain M2 mulai dijalankan maka T1 ditangguhkan selama durasi metode M2 ​​dengan DataSourceTransactionObject T2 baru untuk M2.M2 berjalan dalam konteks transaksi sendiri

PROPAGATION_NOT_SUPPORTED = 4 ; Jika DataSourceTransactionObject T1 sudah mulai untuk Metode M1.Jika metode lain M2 dijalankan secara bersamaan. Maka M2 tidak boleh berjalan dalam konteks transaksi. T1 ditangguhkan hingga M2 selesai.

PROPAGATION_NEVER = 5 ; Tidak ada metode yang berjalan dalam konteks transaksi.

Tingkat isolasi: Ini tentang seberapa besar transaksi dapat dipengaruhi oleh kegiatan transaksi bersamaan lainnya. Ini adalah konsistensi pendukung yang meninggalkan data melintasi banyak tabel dalam keadaan konsisten. Ini melibatkan penguncian baris dan / atau tabel dalam database.

Masalah dengan beberapa transaksi

Skenario 1. Jika transaksi T1 membaca data dari tabel A1 yang ditulis oleh transaksi konkuren lain T2.Jika dalam perjalanan T2 adalah rollback, data yang diperoleh oleh T1 tidak valid.Eg a = 2 adalah data asli. Jika T1 membaca a = 1 yang ditulis oleh T2.Jika T2 rollback maka a = 1 akan rollback ke a = 2 di DB. Namun, Sekarang, T1 memiliki a = 1 tetapi dalam tabel DB diubah menjadi a = 2.

Skenario2 . Jika transaksi T1 membaca data dari tabel A1. Jika transaksi bersamaan lainnya (T2) memperbarui data pada tabel A1. Kemudian data yang dibaca T1 berbeda dari tabel A1. Karena T2 telah memperbarui data pada tabel A1.Eg jika T1 baca a = 1 dan T2 memperbarui a = 2.Lalu a! = b.

Skenario 3. Jika transaksi T1 membaca data dari tabel A1 dengan jumlah baris tertentu. Jika transaksi bersamaan lainnya (T2) menyisipkan lebih banyak baris pada tabel A1. Jumlah baris yang dibaca oleh T1 berbeda dari baris pada tabel A1

Skenario 1 disebut Dirty reads.

Skenario 2 disebut Non-repeatable reads.

Skenario 3 disebut Phantom reads.

Jadi, level isolasi adalah perluasan di mana Skenario 1, Skenario 2, Skenario 3 dapat dicegah. Anda dapat memperoleh tingkat isolasi lengkap dengan menerapkan penguncian. Itu mencegah pembacaan dan penulisan data yang bersamaan terjadi, tetapi hal itu mempengaruhi kinerja. Tingkat isolasi tergantung pada aplikasi ke aplikasi berapa banyak isolasi yang diperlukan.

ISOLATION_READ_UNCOMMITTED : Memungkinkan untuk membaca perubahan yang belum dilakukan. Ini menderita dari Skenario 1, Skenario 2, Skenario 3

ISOLATION_READ_COMMITTED : Memungkinkan pembacaan dari transaksi bersamaan yang telah dilakukan. Mungkin menderita dari Skenario 2 dan Skenario 3. Karena transaksi lain mungkin memperbarui data.

ISOLATION_REPEATABLE_READ : Banyak pembacaan dari bidang yang sama akan menghasilkan hasil yang sama sampai diubah dengan sendirinya. Mungkin menderita Skenario 3.Karena transaksi lain mungkin memasukkan data

ISOLATION_SERIALIZABLE : Skenario 1, Skenario 2, Skenario 3 tidak pernah terjadi. Ini adalah isolasi lengkap. Ini melibatkan penguncian penuh. Ini menghasilkan kinerja karena penguncian.

Anda dapat menguji menggunakan

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();
    }

}

Anda dapat men-debug dan melihat hasilnya dengan nilai yang berbeda untuk isolasi dan propagasi.

abishkar bhattarai
sumber
cara mendapatkan perubahan yang dibuat dalam transaksi saat ini- stackoverflow.com/questions/36132667/…
Prasanna Kumar HA
2
Apa interaksi antara tingkat isolasi dan propagasi ? Jika metode 1 memulai transaksi dengan tingkat isolasi, katakanlah, READ_COMMITTED, dan kemudian memanggil metode2 dengan tingkat REPEATABLE_READ, tentunya metode 2 harus dieksekusi dalam transaksinya sendiri, transaksi baru, terlepas dari perilaku propagasi apa yang ditentukan (misalnya hanya DIBUTUHKAN)?
Cornel Masson
Ini benar-benar terlambat untuk pertunjukan, tetapi ketika PROPAGATION_REQUIRES_NEW, apa yang terjadi pada T1 (yang digunakan oleh M1) jika ada panggilan baru yang terjadi pada M1? (katakanlah M1.1)
Tim Z.
115

Penjelasan yang cukup tentang setiap parameter diberikan oleh jawaban lain; Namun Anda meminta contoh dunia nyata, inilah yang menjelaskan tujuan berbagai opsi propagasi :

Misalkan Anda bertanggung jawab untuk menerapkan layanan pendaftaran di mana email konfirmasi dikirimkan kepada pengguna. Anda datang dengan dua objek layanan, satu untuk mendaftarkan pengguna dan satu untuk mengirim e-mail, yang disebut belakangan di dalam yang pertama. Misalnya sesuatu seperti ini:

/* 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)
 }
}

Anda mungkin telah memperhatikan bahwa layanan kedua adalah tipe propagasi REQUIRES_NEW dan terlebih lagi kemungkinannya melempar pengecualian (server SMTP down, email yang tidak valid atau alasan lain). Anda mungkin tidak ingin seluruh proses untuk roll-back, seperti menghapus informasi pengguna dari basis data atau hal lain; oleh karena itu Anda memanggil layanan kedua dalam transaksi terpisah.

Kembali ke contoh kami, kali ini Anda khawatir tentang keamanan basis data, jadi Anda mendefinisikan kelas DAO Anda dengan cara ini:

/* User DAO */
@Transactional(Propagation=MANDATORY)
class UserDAO{
 // some CRUD methods
}

Berarti bahwa setiap kali objek DAO, dan karenanya potensi akses ke db, dibuat, kita perlu meyakinkan bahwa panggilan itu dilakukan dari dalam salah satu layanan kami, menyiratkan bahwa transaksi langsung harus ada; jika tidak terjadi pengecualian. Oleh karena itu propagasi adalah jenis WAJIB .

kamuaneane
sumber
26
Contoh sempurna untuk REQUIRES_NEW.
Ravi Thapliyal
5
Penjelasan yang bagus! Ngomong-ngomong apa standar untuk propagasi? Juga akan lebih baik jika Anda bisa memberikan contoh seperti ini untuk isolasi juga. Terima kasih banyak.
Prakash K
5
@PrakashK Default DIBUTUHKAN. ( docs.spring.io/spring-framework/docs/current/javadoc-api/org/… )
ihebiheb
59

Level isolasi mendefinisikan bagaimana perubahan yang dilakukan pada beberapa repositori data oleh satu transaksi mempengaruhi transaksi bersamaan simultan lainnya, dan juga bagaimana dan kapan perubahan data menjadi tersedia untuk transaksi lain. Ketika kami mendefinisikan transaksi menggunakan kerangka kerja Spring, kami juga dapat mengonfigurasi tingkat isolasi di mana transaksi yang sama akan dieksekusi.

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

}

READ_UNCOMMITTED tingkat isolasi menyatakan bahwa suatu transaksi dapat membaca data yang masih tidak dikomit oleh transaksi lain.

READ_COMMITTED tingkat isolasi menyatakan bahwa transaksi tidak dapat membaca data yang belum dilakukan oleh transaksi lain.

REPEATABLE_READ tingkat isolasi menyatakan bahwa jika suatu transaksi membaca satu catatan dari database beberapa kali, hasil dari semua operasi pembacaan tersebut harus selalu sama.

Level isolasi SERIALIZABLE adalah yang paling restriktif dari semua level isolasi. Transaksi dijalankan dengan penguncian di semua tingkatan (baca, rentang, dan penguncian tulis) sehingga tampak seolah-olah dieksekusi secara serial.

Propagasi adalah kemampuan untuk memutuskan bagaimana metode bisnis harus dikemas dalam transaksi logis atau fisik.

Perilaku Spring REQUIRED berarti bahwa transaksi yang sama akan digunakan jika ada transaksi yang sudah dibuka dalam konteks eksekusi metode bean saat ini.

Perilaku REQUIRES_NEW berarti bahwa transaksi fisik baru akan selalu dibuat oleh kontainer.

Perilaku NESTED membuat transaksi Spring bersarang untuk menggunakan transaksi fisik yang sama tetapi menetapkan savepoints antara doa bersarang sehingga transaksi dalam juga dapat rollback secara independen dari transaksi luar.

Perilaku WAJIB menyatakan bahwa transaksi terbuka yang ada harus sudah ada. Jika tidak pengecualian akan dibuang oleh wadah.

Perilaku PERNAH menyatakan bahwa transaksi terbuka yang sudah ada harus belum ada. Jika ada transaksi pengecualian akan dibuang oleh kontainer.

Perilaku NOT_SUPPORTED akan mengeksekusi di luar ruang lingkup transaksi apa pun. Jika transaksi terbuka sudah ada, maka akan dijeda.

Perilaku DUKUNGAN akan mengeksekusi dalam lingkup transaksi jika transaksi terbuka sudah ada. Jika tidak ada transaksi yang sudah dibuka, metode akan tetap menjalankan tetapi dengan cara non-transaksional.

reos
sumber
4
Jika Anda bisa menambahkan kapan harus menggunakan yang mana, akan jauh lebih bermanfaat.
Kumar Manish
Berikan beberapa contoh, Ini akan sangat membantu bagi pemula
nitinsridar
23

Transaksi mewakili unit kerja dengan database.

Di TransactionDefinitionantarmuka pegas yang mendefinisikan properti transaksi yang sesuai dengan Spring. @Transactionalanotasi menjelaskan atribut transaksi pada metode atau kelas.

@Autowired
private TestDAO testDAO;

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

  // Interact with testDAO

}

Propagasi (Reproduksi): digunakan untuk hubungan antar transaksi. (analog dengan komunikasi antar thread java)

+-------+---------------------------+------------------------------------------------------------------------------------------------------+
| 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.                                 |
+-------+---------------------------+------------------------------------------------------------------------------------------------------+

Isolasi: Isolasi adalah salah satu properti ACID (Atomicity, Consistency, Isolasi, Durability) dari transaksi basis data. Isolasi menentukan bagaimana integritas transaksi terlihat oleh pengguna dan sistem lain. Ini digunakan untuk penguncian sumber daya yaitu kontrol konkurensi, pastikan hanya satu transaksi yang dapat mengakses sumber daya pada titik tertentu.

Persepsi penguncian: tingkat isolasi menentukan durasi penguncian.

+---------------------------+-------------------+-------------+-------------+------------------------+
| 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     |
+---------------------------+-------------------+-------------+-------------+------------------------+

Baca persepsi: 3 jenis masalah utama berikut terjadi:

  • Bacaan kotor : membaca data yang tidak dikomit dari tx lain (transaksi).
  • Bacaan yang tidak dapat diulang : bacaan yang dilakukan UPDATESdari tx lain.
  • Phantom membaca : membaca berkomitmen INSERTSdan / atau DELETESdari tx lain

Tingkat isolasi dengan berbagai jenis bacaan:

+---------------------------+----------------+----------------------+----------------+
| 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       |
+---------------------------+----------------+----------------------+----------------+

untuk contoh

Premraj
sumber
20

Anda hampir tidak pernah ingin menggunakannya Read Uncommitedkarena tidak benar-benar ACIDsesuai. Read Commmitedadalah tempat awal default yang baik. Repeatable Readmungkin hanya diperlukan dalam skenario pelaporan, rollup, atau agregasi. Perhatikan bahwa banyak DB, postgres yang disertakan sebenarnya tidak mendukung Baca Berulang, Anda harus menggunakannya Serializable. Serializableberguna untuk hal-hal yang Anda tahu harus terjadi sepenuhnya terlepas dari hal lain; pikirkan seperti synchronizeddi Jawa. Serializable berjalan seiring dengan REQUIRES_NEWpropagasi.

Saya menggunakan REQUIRESuntuk semua fungsi yang menjalankan permintaan UPDATE atau DELETE serta fungsi tingkat "layanan". Untuk fungsi level DAO yang hanya menjalankan SELECT, saya menggunakan SUPPORTSyang akan berpartisipasi dalam TX jika sudah dimulai (yaitu dipanggil dari fungsi layanan).

AngerClown
sumber
13

Isolasi Transaksi dan Propagasi Transaksi meskipun terkait tetapi jelas dua konsep yang sangat berbeda. Dalam kedua kasus, default disesuaikan pada komponen batas klien baik dengan menggunakan manajemen transaksi deklaratif atau manajemen transaksi terprogram . Detail setiap level isolasi dan atribut propagasi dapat ditemukan di tautan referensi di bawah ini.

Isolasi Transaksi

Untuk diberikan dua atau lebih transaksi yang berjalan / koneksi ke database, bagaimana dan kapan perubahan dibuat oleh permintaan dalam satu dampak transaksi / terlihat oleh permintaan dalam transaksi yang berbeda. Ini juga terkait dengan jenis penguncian catatan basis data apa yang akan digunakan untuk mengisolasi perubahan dalam transaksi ini dari transaksi lain dan sebaliknya. Ini biasanya diterapkan oleh database / sumber daya yang berpartisipasi dalam transaksi.

.

Propagasi Transaksi

Dalam aplikasi perusahaan untuk setiap permintaan / pemrosesan yang diberikan ada banyak komponen yang terlibat untuk menyelesaikan pekerjaan. Beberapa komponen ini menandai batas (mulai / akhir) dari transaksi yang akan digunakan dalam masing-masing komponen dan sub komponennya. Untuk batas komponen transaksional ini, Propogasi Transaksi menentukan apakah masing-masing komponen akan atau tidak akan berpartisipasi dalam transaksi dan apa yang terjadi jika komponen panggilan sudah atau belum memiliki transaksi yang sudah dibuat / dimulai. Ini sama dengan Atribut Transaksi Java EE. Ini biasanya diterapkan oleh manajer transaksi / koneksi klien.

Referensi:

Gladwin Burboz
sumber
1
Hebat, Semua info di satu tempat, Tautan sangat membantu, Terima kasih @Gwinwin Burboz
nitinsridar
7

Saya telah menjalankan outerMethod, method_1dan method_2dengan mode propagasi yang berbeda.

Di bawah ini adalah output untuk mode propagasi yang berbeda.

  • Metode Luar

    @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 - Tanpa transaksi
      • method_1 - Propagation.MANDATORY) -
      • method_2 - Anotasi transaksi saja
      • Output: method_1 akan mengeluarkan pengecualian yang tidak ada transaksi yang ada
      • outerMethod - Tanpa transaksi
      • method_1 - Anotasi transaksi saja
      • method_2 - Propagation.MANDATORY)
      • Output: method_2 akan mengeluarkan pengecualian yang tidak ada transaksi yang ada
      • Keluaran: method_1 akan bertahan dalam database.
      • outerMethod - Dengan transaksi
      • method_1 - Anotasi transaksi saja
      • method_2 - Propagation.MANDATORY)
      • Output: method_2 akan menyimpan catatan dalam database.
      • Keluaran: method_1 akan bertahan dalam database. - Sini Main Outer transaksi yang ada digunakan untuk kedua metode 1 dan 2
      • outerMethod - Dengan transaksi
      • method_1 - Propagation.MANDATORY) -
      • method_2 - Hanya penjelasan transaksi dan memberikan pengecualian
      • Output: tidak ada catatan yang bertahan dalam database berarti rollback dilakukan.
      • outerMethod - Dengan transaksi
      • method_1 - Propagation.REQUIRES_NEW)
      • method_2 - Propagation.REQUIRES_NEW) dan melempar pengecualian 1/0
      • Output: method_2 akan memunculkan exception sehingga record method_2 tidak bertahan.
      • Keluaran: method_1 akan bertahan dalam database.
      • Output: Tidak ada rollback untuk method_1
NIrav Modi
sumber
3

Kami dapat menambahkan ini:

@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
    }
}
Ankit
sumber
1

Anda bisa menggunakan seperti ini:

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

Anda dapat menggunakan hal ini juga:

public interface TransactionStatus extends SavepointManager {
    boolean isNewTransaction();
    boolean hasSavepoint();
    void setRollbackOnly();
    boolean isRollbackOnly();
    void flush();
    boolean isCompleted();
}
Ankit
sumber