2016-08-31 18 views
16

Ngữ cảnh là Java - JPA với Hibernate và Spring.Chỉ giao dịch chặn khi chắc chắn được cam kết nhưng trước khi cam kết

Hãy lấy kịch bản xác nhận hai pha (nhưng chỉ với một tài nguyên):

  1. Query cam kết từ ứng dụng

  2. Vote Có/Không (từ cơ sở dữ liệu trong trường hợp của chúng tôi)

3.1. Nếu có từ cơ sở dữ liệu

3.1.1. (Gọi lại mã theo số) - không phải là một phần của giao thức

3.1.2. Cam kết cơ sở dữ liệu

3.2 Nếu không

3.2.1 Rollback để cơ sở dữ liệu

Những gì tôi muốn là một cách để làm điều gọi lại từ 3.1.1 trong mã, nhưng chỉ khi nó được biết rằng giao dịch sẽ được cam kết, nhưng trước đây thực sự là cam kết. Ngoài ra, nếu một ngoại lệ được ném vào đây, thì giao dịch sẽ được khôi phục.

Sử dụng TransactionSynchronization (*) từ mùa xuân, cho phép bạn chặn giao dịch trước khi giao dịch được thực hiện/hoàn tất hoặc sau khi giao dịch được thực hiện/hoàn tất.

  • beforeCommit() gọi lại cho biết rằng một cuộn lại vẫn có thể xảy ra sau khi phương pháp được gọi;
  • beforeComplete() được gọi ngay cả khi giao dịch bị lỗi
  • afterCommit/Complete() được gọi sau khi giao dịch thực sự được cam kết với cơ sở dữ liệu và không có cách nào để khôi phục.

Bây giờ tôi có vẻ như những gì tôi muốn là một giao thức cam kết hoàn toàn hai giai đoạn khác; nhưng tôi tự hỏi nếu có một cách giải quyết trong mùa xuân. Sự khác biệt là cuộc gọi được thực hiện trong cuộc gọi lại không thể được khôi phục.

(*) từ mùa xuân 4.2 là rất đơn giản với @TransactionalEventListenerTransactionPhase mà độc đáo tóm tắt TransactionSynchronization

+0

Bạn đang cố gắng bắt chước cam kết hai giai đoạn? Bạn đã thử ''? Nó cung cấp cam kết twophase vào mùa xuân. – Zeus

+0

@Zeus Có, nhưng không đầy đủ; cuộc gọi được thực hiện trong phương thức gọi lại không nên và không thể được cuộn lại. Sẽ xem xét JtaTransactionManager. Không cần phải nói rằng gọi lại chỉ là một cuộc gọi lại mã, không phải là một nguồn lực đầy đủ hàm ý XA. – m3th0dman

+0

Bạn đã xem xét sử dụng Spring PlatformTransactionManager chưa? Kiểm tra tài liệu Spring, đây là giao diện bạn có thể triển khai và truyền. –

Trả lời

1

Tôi chỉ muốn trước tiên quay trở lại giao dịch, là một đơn vị của công việc đó hoặc là tất cả đèo hoặc tất cả thất bại. Với những gì bạn đang nói về phương pháp của bạn về nó, nó không thể được khôi phục lại, và cần phải được thực hiện giữa đầu và cuối của giao dịch, sau đó tôi xin lỗi để nói rằng bạn không có một giao dịch.

Bạn có thể thực hiện rất nhiều kiểm tra trong phương pháp để đảm bảo khả năng cuộn lại cực kỳ mỏng, nhưng sẽ luôn có cơ hội để phương thức của bạn thực thi và khôi phục, nhưng cơ hội này có thể cực kỳ không đáng kể và bạn có thể hài lòng với điều đó, tôi không biết.

Chỉnh sửa: Tôi nghĩ rằng sự tương tự sẽ tốt đẹp.

Trường hợp 1: Ví dụ điển hình về giao dịch mua chuối tại cửa hàng, nếu bạn không có tiền hoặc cửa hàng không có chuối, cửa hàng không nhận tiền, bạn không nhận được một quả chuối, đây là những gì thường xảy ra. Nhưng nếu tất cả các điều kiện được thiết lập thì giao dịch sẽ thành công.

Trường hợp 2: Bây giờ cho những gì bạn đang yêu cầu. Đối với lợi ích cho phép nói rằng bạn là một tên trộm, và bạn chỉ muốn ăn cắp chuối nếu bạn sẽ nhận được đi với nó. Bạn không thể biết điều này chắc chắn, bởi vì bạn hỏi về tương lai, trừ khi bạn là một thầy bói, khi bạn đi ăn cắp chuối bạn có thể bị bắt.

Nếu bạn quay trở lại trường hợp đầu tiên, bạn có thể kiểm tra xem bạn có tiền không, cửa hàng có chuối, cung cấp cho cửa hàng tiền của bạn, ném tất cả khách hàng ra ngoài, khóa cửa vào cửa hàng để cửa hàng ở một trạng thái không thể thay đổi. Đi làm phương pháp của bạn mà bạn không thể rollback, trở lại cửa hàng, và lấy chuối. Không ai có thể đảm bảo với bạn rằng chuối sẽ vẫn ở đó, nhưng rất có thể.

+0

Tôi không muốn một giao dịch với phương thức đó không thể được khôi phục. Tôi chỉ muốn chặn giao dịch cơ sở dữ liệu và gọi phương thức đó nếu giao dịch cơ sở dữ liệu thành công; và cơ sở dữ liệu biết/có thể làm điều này vì nó hỗ trợ đầy đủ các giao dịch XA. Đây là một vấn đề kỹ thuật không phải là một vấn đề lý thuyết; hoặc một vấn đề đặt tên. – m3th0dman

+0

Tôi nghĩ bạn hơi khắc nghiệt với downvote. Bạn sẽ thấy những gì tôi đã nói được lặp lại ở đây: http://stackoverflow.com/questions/128377/what-is-the-best-way-to-do-distributed-transactions-across-multiple-databases. – Snickers3192

1

Trường hợp của bạn là một trong các tài nguyên của bạn không tương thích với cam kết hai pha (không phải XA có khả năng). Ý tưởng của bạn đi theo hướng mô hình mô tả trong đoạn XA và Resource cuối Gambit của http://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-without-xa.html

Việc sử dụng các Gambit tài nguyên cuối cùng là giải thích ngắn gọn trong câu trả lời của How to set up Spring Boot + Bitronix + non-XA Datasource + XA JMS Connection

Bằng cách này, câu hỏi của bạn không đề cập đến việc triển khai trình quản lý giao dịch nào bạn sử dụng (JBossTS, Bitronix JTA, Atomikos Transaction Essentials, ...).

+0

Không có trình quản lý giao dịch XA vì nó không cần thiết vì chỉ có cơ sở dữ liệu hỗ trợ nó. – m3th0dman

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