2010-08-27 40 views
6

Tất cả những gì tôi đọc về Hibernate nói rằng bạn phải quay trở lại giao dịch và đóng phiên giao dịch khi một lỗi xảy ra, và có thường một số biến thể của mã sau (lấy từ tài liệu của Hibernate) cho là một ví dụ:Điều gì sẽ xảy ra nếu bạn không quay trở lại giao dịch trong Hibernate?

Session sess = factory.openSession(); 
Transaction tx = null; 
try { 
    tx = sess.beginTransaction(); 
    // do some work 
    ... 
    tx.commit(); 
} catch (RuntimeException e) { 
    if (tx != null) tx.rollback(); 
    throw e; // or display error message 
} finally { 
    sess.close(); 
} 

Mô hình này có vẻ lạ với tôi vì một vài lý do. Đầu tiên, nó có vẻ phức tạp một cách không hợp lý cho một khung công tác thường hướng tới việc làm cho mọi thứ trở nên đơn giản. Quan trọng hơn, điều gì sẽ xảy ra nếu mã trong khối try ném thứ gì đó khác với một số RuntimeException? Dường như Hibernate phải có khả năng kết thúc phiên giao dịch một cách duyên dáng với một giao dịch mở trong trường hợp đó, có lẽ bằng cách chuyển nó trở lại, nhưng nếu đó là sự thật, tại sao bận tâm gọi rollback ở tất cả?

+2

Ai đã nói với bạn Hibernate khiến mọi việc đơn giản? :) – skaffman

Trả lời

4

Hibernate có thể làm cho rất nhiều điều đơn giản hơn, nhưng quản lý giao dịch không phải là rất đơn giản vì vậy cho mỗi giao dịch bạn phải suy nghĩ rất cẩn thận những gì bạn muốn. Hibernate không thể giúp bạn với điều đó.

Nếu mã trong khối try ném bất kỳ thứ gì khác ngoài RuntimeException, giao dịch của bạn rõ ràng không cam kết. Nhưng bạn cũng không quay lại một cách rõ ràng. Cuộc gọi sess.Close trong số finally khối của bạn cũng không quay lại giao dịch. Điều gì xảy ra tùy thuộc vào việc đây có phải là giao dịch lồng nhau hay không:

  • Nếu không, thì cuối cùng giao dịch hết giờ và quay lại.
  • Nếu có, giao dịch cha mẹ sẽ thấy rằng giao dịch con chưa cam kết khi giao dịch tự thực hiện. Điều này sẽ dẫn đến việc khôi phục toàn bộ giao dịch.
0

Quan trọng hơn, những gì sẽ xảy ra nếu các mã trong khối try ném một cái gì đó khác hơn là một RuntimeException?

Nếu bất kỳ ngoại lệ nào khác có thể xảy ra trong khối mã trong khối thử ngoài RuntimeException, sẽ phải là ngoại lệ được kiểm tra, sẽ bị trình biên dịch bắt và bạn sẽ kết thúc trong việc kết hợp phần xử lý của nó trong mã của bạn.

Trong ví dụ được cung cấp trong câu hỏi này, chúng tôi đang bắt chỉ RuntimeException mà tôi cảm thấy là đúng cách để mã. Bằng cách này, chúng tôi có thể khôi phục giao dịch ngay lập tức mà không phải đợi thời gian giao dịch và thời gian hoàn tiền cuối cùng. Khi chúng ta tiếp tục ném lại RuntimeException, chúng ta cũng không phá vỡ luồng ngoại lệ. Đây là cách làm việc rõ ràng và rõ ràng hơn làm việc với giao dịch hơn là để thời gian chờ giao dịch kích hoạt quá trình quay lại giao dịch.

Tất nhiên, chúng ta KHÔNG nên bắt 'Ngoại lệ' theo cách RuntimeException bị bắt vì lý do hiển nhiên.

Các vấn đề liên quan