2012-10-24 24 views
30

Tôi có một phương pháp mà có propagation = Propagation.REQUIRES_NEW bất động sản giao dịch:giao dịch mùa xuân YÊU CẦU vs REQUIRES_NEW: Rollback Transaction

@Transactional(propagation = Propagation.REQUIRES_NEW) 
public void createUser(final UserBean userBean) { 
    //Some logic here that requires modification in DB 
} 

Phương pháp này có thể được gọi nhiều lần cùng một lúc, và cho mỗi giao dịch nếu xảy ra lỗi hơn nó được khôi phục (độc lập với các giao dịch khác).

Vấn đề là điều này có thể buộc Spring tạo nhiều giao dịch, ngay cả khi có giao dịch khác và có thể gây ra một số vấn đề về hiệu suất.


Java doc của propagation = Propagation.REQUIRED nói: Support a current transaction, create a new one if none exists.

Điều này dường như giải quyết vấn đề hiệu suất, đúng không?

Còn vấn đề về rollback thì sao? Điều gì sẽ xảy ra nếu một cuộc gọi phương thức mới cuộn lại trong khi sử dụng một giao dịch hiện có? sẽ không khôi phục lại toàn bộ giao dịch ngay cả các cuộc gọi trước đó?

[EDIT] Tôi đoán câu hỏi của tôi là không đủ rõ ràng:

Chúng tôi có hàng trăm khách hàng kết nối với máy chủ của chúng tôi.

Đối với mỗi khách hàng, chúng tôi cần gửi phản hồi về giao dịch (OK hoặc ngoại lệ -> rollback).

Câu hỏi của tôi là: nếu tôi sử dụng REQUIRED, điều đó có nghĩa là chỉ một giao dịch được sử dụng và nếu khách hàng thứ 100 gặp phải sự cố thì giao dịch của khách hàng thứ nhất sẽ quay trở lại?

+1

đó là điểm của REQUIRES_NEW, để tạo giao dịch mới mỗi khi phương thức được gọi. Và có, nếu bạn đã YÊU CẦU và giao dịch được quay trở lại, nó sẽ quay trở lại toàn bộ điều. –

+0

@DenisTulskiy toàn bộ mọi thứ là mọi cuộc gọi trước đó cho fonction đó, hoặc ngăn xếp cuộc gọi hiện tại? –

+2

@jidma: toàn bộ giao dịch, xem câu trả lời của @ Eugen, nếu 'createUser' là phương thức đầu tiên mà mã khách hàng của bạn gọi, thì REQUIRES_NEW và YÊU CẦU là cùng một điều –

Trả lời

48

Sử dụng REQUIRES_NEW chỉ liên quan khi phương thức được gọi từ ngữ cảnh giao dịch; khi phương thức được gọi từ ngữ cảnh phi giao dịch, nó sẽ hoạt động chính xác như REQUIRED - nó sẽ tạo một giao dịch mới.

Điều đó không có nghĩa là sẽ chỉ có một giao dịch duy nhất cho tất cả khách hàng của bạn - mỗi khách hàng sẽ bắt đầu từ ngữ cảnh phi giao dịch và ngay sau khi xử lý yêu cầu sẽ đạt số @Transactional. Giao dịch.Vì vậy, với ý nghĩ đó, nếu sử dụng REQUIRES_NEW có ý nghĩa cho ngữ nghĩa của hoạt động đó - hơn là tôi sẽ không lo lắng về hiệu suất - điều này sẽ giúp tối ưu hóa sách giáo khoa sớm - tôi thà nhấn mạnh tính chính xác và toàn vẹn dữ liệu và lo lắng về hiệu suất khi số liệu hiệu suất đã được thu thập và không phải trước đây.

Khi khôi phục - sử dụng REQUIRES_NEW sẽ buộc bắt đầu giao dịch mới và do đó ngoại lệ sẽ khôi phục giao dịch đó. Nếu cũng có một giao dịch khác đang được thực hiện tốt - điều đó sẽ hoặc sẽ không được khôi phục tùy thuộc vào trường hợp ngoại lệ bong bóng lên ngăn xếp hoặc bị bắt - lựa chọn của bạn, dựa trên chi tiết cụ thể của các hoạt động. Ngoài ra, để có một cuộc thảo luận sâu hơn về các chiến lược giao dịch và rollback, tôi sẽ giới thiệu: «Transaction strategies: Understanding transaction pitfalls», Mark Richards.

+0

Bạn có thể xem câu hỏi này https://stackoverflow.com/questions/44539861/spring-transactional-commit-failures-deby-eclipselink không? tôi có cần 'REQUIRES_NEW', phản hồi được đưa ra sau khi pesist được thực hiện sau một thời gian nó được khôi phục. – vels4j

10

Nếu bạn thực sự cần thực hiện trong giao dịch riêng, bạn cần sử dụng REQUIRES_NEW và sống với chi phí hoạt động. Xem ra cho khóa chết.

Tôi muốn làm điều đó theo cách khác:

  • dữ liệu Validate đứng về phía Java.
  • Chạy mọi thứ trong một giao dịch.
  • Nếu có gì sai về phía DB -> đó là lỗi chính của DB hoặc thiết kế xác thực. Rollback tất cả mọi thứ và ném lỗi cấp cao nhất quan trọng.
  • Viết các bài kiểm tra đơn vị tốt.
+0

Chúng tôi có hàng trăm khách hàng được kết nối với máy chủ của chúng tôi. Đối với mỗi khách hàng, chúng tôi cần gửi phản hồi về giao dịch (OK hoặc ngoại lệ -> rollback). Câu hỏi của tôi vẫn là: nếu tôi sử dụng 'REQUIRED', điều đó có nghĩa là chỉ một giao dịch được sử dụng và nếu khách hàng thứ 100 gặp sự cố thì giao dịch của khách hàng đầu tiên sẽ quay trở lại? –