Transaction's Propagation in Spring

Bài viết này sẽ cung cấp các kiến thức về việc truyền transaction trong Spring framework. Thông qua bài viết này, developer có thể quyết định các method nghiệp vụ có thể được đóng gói trong logical hoặc physical transactions. Các method trong các Spring beans riêng biệt chia qua một tập các transactions. Cụ thể của điều này giống như là làm thế nào để kết quả đầu ra của một inner transaction ảnh hưởng đến các transactions bên ngoài. Sự khác biệt này sẽ được trình bày cụ thể dưới đây. Bài viết này sẽ chỉ tập trung vào việc lan truyền của transaction. Sau đây là các behavior của một transaction được khai báo trong Spring:

  1. REQUIRED behavior Spring REQUIRED behavior có nghĩa một transaction sẽ được sử dụng lại tại context của method bean hiện tại. Nếu không có transaction nào tồn tại thì Spring container sẽ tạo mới một transaction. Nếu nhiều method được cấu hình là REQUIRED behavior được gọi thì chúng sẽ được gán vào một logical transaction riêng biệt, nhưng chúng sẽ chung một physical transaction. Nói các khác, nếu một inner method gây ra rollback cho 1 transaction thì outer method sẽ ko thể commit và sẽ rollback transaction đó. Ví dụ như ở dưới: Outer bean

` @Autowired

private TestDAO testDAO;

@Autowired

private InnerBean innerBean;

@Override

@Transactional(propagation=Propagation.REQUIRED)

public void testRequired(User user) {

testDAO.insertUser(user);

try{

innerBean.testRequired();

} catch(RuntimeException e){

// handle exception

}

}`

Inner bean

` @Override

@Transactional(propagation=Propagation.REQUIRED)

public void testRequired() {

throw new RuntimeException("Rollback this transaction!");

}`

Ở đây, inner method throw một RuntimeException và nó được mark là REQUIRED behavior. Điều này có nghĩa là nó sẽ sử dụng cùng transaction với outer bean, vì vậy outer transaction sẽ ko thể commit và nó sẽ rollback. Nếu muốn checked các exceptions để set rollback cho các exceptions đó thì cần phải configure chúng. Như ví dụ trên, sẽ chỉ rollback khi gặp RuntimeException. 2. REQUIRED_NEW behavior REQUIRED_NEW behavior có nghĩa một physical transaction sẽ luôn được tạo bởi 1 container. Nói cách khác, inner transaction sẽ commit hoặc rollback độc lập với outer transaction. Ví dụ outer transaction sẽ không ảnh hưởng bởi kết quả inner transaction, chúng sẽ chỉ chạy trong các physical transaction riêng biệt: Outer bean

@Autowired

private TestDAO testDAO;

@Autowired

private InnerBean innerBean;

@Override

@Transactional(propagation=Propagation.REQUIRED)

public void testRequiresNew(User user) {

testDAO.insertUser(user);

try{

innerBean.testRequiresNew();

} catch(RuntimeException e){

// handle exception

}

}

Inner bean

@Override

@Transactional(propagation=Propagation.REQUIRES_NEW)

public void testRequiresNew() {

throw new RuntimeException("Rollback this transaction!");

}

  1. NESTED behavior NESTED behavior sẽ làm cho các Spring transactions sử dụng chung physical transaction nhưng sẽ thiết lập các savepoints giữa các lời gọi để các inner transactions có thể rollback độc lập với outer transactions. Điều này khá giống với savepoints của JDBC, vì vậy behavior này chỉ thường được sử dụng với Spring JDBC managed transactions.
  2. MANDATORY behavior MANDATORY behavior là một contract đảm bảo rằng đã có một transaction được open trước đó. Nếu không sẽ throw một exception by container. 5.NEVER behavior NEVER behavior ngược lại với MANDATORY behavior, nó đảm bảo cho việc không tồn tại một transaction nào trước đó. Nếu trước đó đã có 1 transaction sẽ throw một exception.
  3. NOT_SUPPORTED behavior NOT_SUPPORTED behavior sẽ thực hiện bên ngoài scope của bất kì transaction. Nếu một transaction đã được open thì nó sẽ được dừng lại.
  4. SUPPORT behavior SUPPORT behavior đảm bảo việc thực hiện bên trong scope của một transaction. Nếu chưa có transaction nào được mở thì method sẽ method vẫn được thực hiện. Hi vọng sau bài viết này người đọc có thể có cái nhìn chính xác về việc lan truyền của transaction giúp cho việc quản lí transaction tốt hơn.