Đảm bảo tính thống nhất trong giao dịch với DDD


9

Tôi đang bắt đầu với DDD và hiểu rằng rễ tổng hợp được sử dụng để đảm bảo tính nhất quán xuyên quốc gia. Chúng ta không nên sửa đổi nhiều tập hợp trong một dịch vụ ứng dụng.

Tuy nhiên, tôi muốn biết làm thế nào để đối phó với tình huống sau đây.

Tôi có một gốc tổng hợp được gọi là Sản phẩm.

Ngoài ra còn có một gốc tổng hợp được gọi là Nhóm.

Cả hai đều có Id và có thể được chỉnh sửa độc lập.

Nhiều sản phẩm có thể trỏ đến cùng một nhóm.

Tôi có một dịch vụ ứng dụng có thể thay đổi nhóm sản phẩm:

ProductService.ChangeProductGroup(string productId, string groupId)

  1. Kiểm tra nhóm tồn tại
  2. Nhận sản phẩm từ kho lưu trữ
  3. Đặt nhóm của nó
  4. Viết sản phẩm trở lại kho lưu trữ

Tôi cũng có một dịch vụ ứng dụng nơi nhóm có thể bị xóa:

GroupService.DeleteGroup(string groupId) 1. Nhận sản phẩm từ kho lưu trữ có groupId được đặt thành groupId được cung cấp, đảm bảo số lượng là 0 hoặc hủy bỏ 2. Xóa nhóm khỏi kho lưu trữ nhóm 3. Lưu thay đổi

Câu hỏi của tôi là kịch bản sau đây, điều gì sẽ xảy ra nếu:

Trong ProductService.Change Producttgroup, chúng tôi kiểm tra nhóm tồn tại (sau đó), sau khi kiểm tra, một người dùng riêng biệt sẽ xóa sản phẩm Groupgroup (thông qua GroupService.Deletegroup khác). Trong trường hợp này, chúng tôi đặt tham chiếu đến một sản phẩm vừa bị xóa?

Đây có phải là một lỗ hổng trong thiết kế của tôi ở chỗ tôi nên sử dụng một thiết kế tên miền khác (thêm các yếu tố bổ sung nếu cần thiết) hay tôi sẽ phải sử dụng các giao dịch?

Câu trả lời:


2

Chúng tôi có cùng một vấn đề.

Và tôi không có cách nào để giải quyết vấn đề này nhưng với các giao dịch hoặc kiểm tra tính nhất quán tại DB để có một ngoại lệ trong trường hợp xấu nhất.

Bạn cũng có thể sử dụng khóa bi quan, chặn gốc tổng hợp hoặc chỉ các bộ phận của nó cho các khách hàng khác cho đến khi giao dịch kinh doanh được hoàn thành ở mức độ nào đó tương đương với giao dịch tuần tự.

Cách bạn đi rất nhiều phụ thuộc vào hệ thống và logic kinh doanh của bạn.
Đồng thời không phải là một nhiệm vụ dễ dàng.
Ngay cả khi bạn có thể phát hiện ra một vấn đề, bạn sẽ giải quyết nó như thế nào? Chỉ cần hủy hoạt động hoặc cho phép người dùng 'hợp nhất' thay đổi?

Chúng tôi sử dụng Entity Framework và EF6 sử dụng read_commited_snapshot theo mặc định, do đó hai lần đọc liên tiếp từ kho lưu trữ có thể cung cấp cho chúng tôi dữ liệu không nhất quán. Chúng tôi chỉ ghi nhớ điều đó cho tương lai khi các quy trình kinh doanh sẽ được vạch ra rõ ràng hơn và chúng tôi có thể đưa ra quyết định từ bên ngoài. Và vâng, chúng tôi vẫn kiểm tra tính nhất quán ở cấp độ mô hình như bạn làm. Điều này ít nhất cho phép kiểm tra BL riêng biệt với DB.

Tôi cũng đề nghị bạn suy nghĩ về tính nhất quán của kho lưu trữ trong trường hợp bạn có các giao dịch kinh doanh 'dài'. Nó là khá khó khăn khi nó bật ra.


1

Tôi nghĩ rằng đây không phải là một câu hỏi cụ thể về Thiết kế hướng tên miền, mà là một câu hỏi quản lý tài nguyên.

Tài nguyên đơn giản phải được khóa khi chúng có được .

Điều này đúng khi dịch vụ ứng dụng biết trước rằng tài nguyên thu được ( Grouptổng hợp, trong ví dụ của bạn) sẽ được sửa đổi. Trong Thiết kế hướng tên miền, khóa tài nguyên là một khía cạnh thuộc về kho lưu trữ.


Không, khóa không phải là "phải". Trên thực tế, đó là một điều khá kinh khủng với các giao dịch dài hạn. Tốt hơn hết là bạn nên sử dụng đồng thời lạc quan, điều mà mọi ORM hiện đại đều hỗ trợ. Và điều tuyệt vời về sự tương tranh lạc quan là nó cũng hoạt động với các cơ sở dữ liệu phi giao dịch, miễn là chúng hỗ trợ các cập nhật nguyên tử.
Aaronaught

1
Tôi đồng ý về những hạn chế của việc khóa bên trong các giao dịch dài hạn, nhưng kịch bản được mô tả bởi @ g18c có gợi ý hoàn toàn ngược lại, đó là các hoạt động ngắn gọn trên các tổng hợp riêng lẻ.
rucamzu

0

Tại sao bạn không lưu trữ id sản phẩm trong thực thể Nhóm? Bằng cách này, bạn chỉ làm việc với một tổng hợp duy nhất sẽ giúp mọi việc dễ dàng hơn.

Sau đó, bạn sẽ cần triển khai một số loại mẫu đồng thời, ví dụ: Nếu bạn chọn đồng thời lạc quan, chỉ cần thêm thuộc tính phiên bản vào thực thể Nhóm và ném ngoại lệ nếu các phiên bản không khớp khi cập nhật tức là

Thêm sản phẩm vào một nhóm

  1. Kiểm tra xem sản phẩm có tồn tại không
  2. Lấy nhóm từ kho lưu trữ (bao gồm cả thuộc tính id phiên bản của nó)
  3. Nhóm.Add (ProductId)
  4. Lưu nhóm bằng cách sử dụng kho lưu trữ (cập nhật với id phiên bản mới và thêm mệnh đề where để đảm bảo phiên bản không bị thay đổi.)

Rất nhiều ORM có tính đồng thời lạc quan được tích hợp trong việc sử dụng id phiên bản hoặc dấu thời gian nhưng bạn có thể dễ dàng cuộn riêng. Đây là một bài viết hay về cách nó được thực hiện trong Nhibernate http://ayende.com/blog/3946/nhibernate-mapping-concurrency .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.