Có nhiều giải pháp thỏa hiệp hơn tôi thấy thoải mái. Cấp, nếu trường hợp sử dụng của bạn phức tạp, chẳng hạn như chuyển tiền giữa các ngân hàng khác nhau, các lựa chọn thay thế dễ chịu hơn có thể là không thể. Nhưng hãy xem những gì chúng ta có thể làm trong kịch bản chung, nơi việc sử dụng microservice can thiệp vào các giao dịch cơ sở dữ liệu của chúng ta.
Tùy chọn 1: Tránh sự cần thiết cho các giao dịch nếu tất cả có thể
Rõ ràng và được đề cập trước đó, nhưng lý tưởng nếu chúng ta có thể quản lý nó. Các thành phần có thực sự thuộc về cùng một dịch vụ không? Hoặc chúng ta có thể thiết kế lại (các) hệ thống sao cho giao dịch trở nên không cần thiết? Có lẽ chấp nhận phi giao dịch là sự hy sinh hợp lý nhất.
Tùy chọn 2: Sử dụng hàng đợi
Nếu có đủ chắc chắn rằng dịch vụ kia sẽ thành công ở bất cứ điều gì chúng tôi muốn nó làm, chúng tôi có thể gọi nó thông qua một số hình thức xếp hàng. Mục được xếp hàng sẽ không được chọn cho đến sau này, nhưng chúng tôi có thể đảm bảo rằng mục đó được xếp hàng .
Ví dụ: giả sử rằng chúng tôi muốn chèn một thực thể và gửi e-mail, dưới dạng một giao dịch. Thay vì gọi máy chủ thư, chúng tôi xếp hàng e-mail trong một bảng.
Begin transaction
Insert entity
Insert e-mail
Commit transaction
Một nhược điểm rõ ràng là nhiều dịch vụ siêu nhỏ sẽ cần truy cập vào cùng một bảng.
Tùy chọn 3: Thực hiện công việc bên ngoài lần cuối, ngay trước khi hoàn thành giao dịch
Cách tiếp cận này dựa trên giả định rằng việc thực hiện giao dịch rất khó xảy ra.
Begin transaction
Insert entity
Insert another entity
Make external call
Commit transaction
Nếu các truy vấn không thành công, cuộc gọi bên ngoài chưa được thực hiện. Nếu cuộc gọi bên ngoài thất bại, giao dịch không bao giờ được cam kết.
Cách tiếp cận này đi kèm với những hạn chế mà chúng tôi chỉ có thể thực hiện một cuộc gọi bên ngoài và nó phải được thực hiện sau cùng (nghĩa là chúng tôi không thể sử dụng kết quả của nó trong các truy vấn của mình).
Tùy chọn 4: Tạo mọi thứ trong trạng thái chờ xử lý
Như được đăng ở đây , chúng ta có thể có nhiều microservice tạo các thành phần khác nhau, mỗi thành phần ở trạng thái chờ xử lý, không giao dịch.
Bất kỳ xác nhận được thực hiện, nhưng không có gì được tạo ra trong trạng thái dứt khoát. Sau khi mọi thứ đã được tạo thành công, mỗi thành phần được kích hoạt. Thông thường, thao tác này rất đơn giản và tỷ lệ xảy ra sự cố rất nhỏ, thậm chí chúng tôi có thể thích thực hiện kích hoạt không giao dịch.
Hạn chế lớn nhất có lẽ là chúng ta phải tính đến sự tồn tại của các mặt hàng đang chờ xử lý. Bất kỳ truy vấn chọn cần xem xét liệu có bao gồm dữ liệu đang chờ xử lý hay không. Hầu hết nên bỏ qua nó. Và cập nhật là một câu chuyện khác hoàn toàn.
Tùy chọn 5: Hãy để microservice chia sẻ truy vấn của nó
Không có lựa chọn nào khác làm điều đó cho bạn? Sau đó, hãy nhận được không chính thống .
Tùy thuộc vào công ty, điều này có thể không được chấp nhận. Tôi biết. Điều này là không chính thống. Nếu nó không được chấp nhận, hãy đi một con đường khác. Nhưng nếu điều này phù hợp với tình huống của bạn, nó sẽ giải quyết vấn đề một cách đơn giản và mạnh mẽ. Nó có thể chỉ là sự thỏa hiệp dễ chấp nhận nhất.
Có một cách để biến các truy vấn từ nhiều dịch vụ siêu nhỏ thành một giao dịch cơ sở dữ liệu đơn giản.
Trả về truy vấn, thay vì thực hiện nó.
Begin transaction
Execute our own query
Make external call, receiving a query
Execute received query
Commit transaction
Mạng khôn ngoan, mỗi microservice cần có thể truy cập từng cơ sở dữ liệu. Hãy ghi nhớ điều này, cũng liên quan đến việc nhân rộng trong tương lai.
Nếu các cơ sở dữ liệu liên quan đến giao dịch nằm trên cùng một máy chủ, đây sẽ là một giao dịch thông thường. Nếu chúng ở trên các máy chủ khác nhau, nó sẽ là một giao dịch phân tán. Mã là như nhau bất kể.
Chúng tôi nhận được truy vấn, bao gồm loại kết nối, tham số và chuỗi kết nối của nó. Chúng ta có thể gói nó trong một lớp Lệnh thực thi gọn gàng, giữ cho luồng có thể đọc được: Cuộc gọi microservice kết quả trong một Lệnh, mà chúng ta thực thi, như một phần của giao dịch của chúng ta.
Chuỗi kết nối là thứ mà microservice khởi tạo mang lại cho chúng ta, vì vậy đối với tất cả ý định và mục đích, truy vấn vẫn được coi là được thực hiện bởi microservice đó. Chúng tôi chỉ định tuyến vật lý thông qua microservice khách hàng. Điều đó làm cho một sự khác biệt? Chà, nó cho phép chúng ta đặt nó trong cùng một giao dịch với một truy vấn khác.
Nếu sự thỏa hiệp có thể chấp nhận được, cách tiếp cận này mang lại cho chúng ta tính giao dịch đơn giản của một ứng dụng nguyên khối, trong một kiến trúc microservice.