Trong một thời gian dài, tôi đã từng thực hiện một hệ thống kiểm tra phức tạp để có thể sử dụng các giao dịch cơ sở dữ liệu. Logic giao dịch diễn ra như sau: mở một giao dịch, thực hiện các hoạt động cơ sở dữ liệu, phục hồi khi có lỗi hoặc cam kết thành công. Sự phức tạp đến từ những gì xảy ra khi bạn muốn một hoạt động bổ sung được thực hiện trong cùng một giao dịch. Bạn cần phải viết một phương thức thứ hai hoàn toàn cho cả hai thao tác hoặc bạn có thể gọi phương thức ban đầu của mình từ một giây, chỉ mở một giao dịch nếu một phương thức chưa được mở và cam kết / quay lại thay đổi chỉ khi bạn là một để mở giao dịch.
Ví dụ:
public void method1() {
boolean selfOpened = false;
if(!transaction.isOpen()) {
selfOpened = true;
transaction.open();
}
try {
performDbOperations();
method2();
if(selfOpened)
transaction.commit();
} catch (SQLException e) {
if(selfOpened)
transaction.rollback();
throw e;
}
}
public void method2() {
boolean selfOpened = false;
if(!transaction.isOpen()) {
selfOpened = true;
transaction.open();
}
try {
performMoreDbOperations();
if(selfOpened)
transaction.commit();
} catch (SQLException e) {
if(selfOpened)
transaction.rollback();
throw e;
}
}
Xin lưu ý, tôi không ủng hộ mã trên bằng bất kỳ phương tiện nào. Điều này sẽ phục vụ như là một ví dụ về những gì không nên làm!
Có vẻ ngớ ngẩn khi tạo ra một phương thức thứ hai để thực hiện logic tương tự như phương pháp thứ nhất cộng thêm thứ gì đó, nhưng tôi muốn có thể gọi phần API cơ sở dữ liệu của chương trình và loại bỏ các vấn đề ở đó. Tuy nhiên, trong khi điều này giải quyết được một phần vấn đề của tôi, mọi phương pháp tôi đã viết đều liên quan đến việc thêm logic dài dòng này để kiểm tra xem một giao dịch đã mở chưa, và cam kết / khôi phục thay đổi nếu phương thức của tôi mở nó.
Vấn đề là khái niệm. Tôi không nên cố gắng nắm lấy mọi kịch bản có thể. Cách tiếp cận đúng là sử dụng logic giao dịch nội bộ trong một phương thức duy nhất lấy phương thức thứ hai làm tham số sẽ thực hiện logic cơ sở dữ liệu thực tế. Logic đó giả định rằng giao dịch là mở và thậm chí không thực hiện kiểm tra. Các phương thức này có thể được gọi kết hợp để các phương thức này không bị lộn xộn với logic giao dịch không cần thiết.
Lý do tôi đề cập đến điều này là vì sai lầm của tôi là cho rằng tôi cần phải làm cho phương pháp của mình hoạt động trong mọi tình huống. Khi làm như vậy, không chỉ phương thức được gọi của tôi là kiểm tra nếu một giao dịch được mở, mà cả những phương thức mà nó được gọi. Trong trường hợp này, nó không phải là một thành tích lớn, nhưng nếu nói, tôi cần xác minh sự tồn tại của một bản ghi trong cơ sở dữ liệu trước khi tiếp tục, tôi sẽ kiểm tra mọi phương thức yêu cầu khi tôi chỉ cần giả định tất cả người gọi nên được biết rằng hồ sơ nên tồn tại. Nếu phương thức được gọi bằng mọi cách, đây là hành vi không xác định và bạn không cần phải lo lắng về những gì sẽ xảy ra.
Thay vào đó, bạn nên cung cấp nhiều tài liệu và viết những gì bạn mong đợi là đúng trước khi thực hiện cuộc gọi theo phương thức của bạn. Nếu nó đủ quan trọng, hãy thêm nó dưới dạng một nhận xét trước phương thức của bạn để không có lỗi (javadoc cung cấp hỗ trợ tốt cho loại điều này trong java).
Tôi hy vọng điều đó sẽ giúp!