What is a Combo Repository and a Service Bus?

2019-08-23 22:24发布

I am learning more about NoSQL and specifically DynamoDB. I recently asked this question: Mapping database structure from SQL Server to DynamoDB

In the comments under the accepted answer; the answers refers to a Service Bus and a Combo repository.

Q1) Is this a Service Bus? (see EventListener class): http://enterprisecraftsmanship.com/2015/05/06/combining-sql-server-and-mongodb-using-nhibernate/

Q2) What is a Combo repository? Is it a "Combination" repository i.e. some methods interface with multiple databases (SQL Server and DynamoDB).

I would usually ask the answerer, however we started to divert from the original post in the other question - the answerer mentioned this. Therefore I have decided to ask another question.

1条回答
我欲成王,谁敢阻挡
2楼-- · 2019-08-23 22:57

I am thinking about using a NoSQL database to scale database reads

Good idea. It sounds like you are going down the path of Command Query Responsibility Segregation(CQRS). NoSql databases make for excellent read stores.

The link you referenced describes a technique to update Combining SQL Server and MongoDB using NHibernate - this is what I meant by 'Combo' (combining) Repository. "Combo Repository" isn't a standard pattern. Quoting the author:

Of course, theoretically, we could just move all the data to some NoSQL storage, but what if we don’t want to get rid of our relational database completely? How can we combine them together?

You've tagged your original question with both a Sql-Server and a NoSql database, so at a guess you're in the Polyglot space

The Repository Pattern is a very common abstraction layer around data persistence.

The "combining" link you've referenced specifically solves the problem of many-to-many relationships (often referred to as Junction tables in Sql), and the performance implications when there are many such relations.

In the more general sense, as an alternative to providing interception points in NHibernate, you may / may not have abstracted data access via the repository pattern.

Here's an ultra simple (and non-generic) repository interface in C#:

public interface IWidgetRepository
{
     Task<Widget> FetchWidget(string widgetKey);
     Task SaveWidget(Widget toBeSaved);
}   

Suppose we already have a SqlRepository:

public class SqlWidgetRepository : IWidgetRepository
{
     public async Task<Widget> FetchWidget(string widgetKey)
     {
         ... Code to use Obtain an NHibernate session and retrieve and deserialize Widget
     }
    ... Other methods here
}   

You could also choose to provide a MongoDb implementation

public class MongoWidgetRepository : IWidgetRepository
{
     public async Task<Widget> FetchWidget(string widgetKey)
     {
        ... Code to connect to a MongoDb secondary and Find() the 
           widget and deserialiaze into Widget
     }
    ... Other methods here
}   

And to maintain both databases simultaneously, here's an example of how this "combo" repository may look:

public class ComboWidgetRepository : IWidgetRepository
{
     private readonly IWidgetRepository _repo1;
     private readonly IWidgetRepository _repo2;

     public ComboWidgetRepository(IWidgetRepository repo1, IWidgetRepository repo2)
     {
          repo1 = repo1;
          repo1 = repo2;
     }

     public async Task<Widget> FetchWidget(string widgetKey)
     {
          // Just need the one ... first one wins
          return await Task.WhenAny(repo1.FetchWidget(widgetKey), 
                                    repo2.FetchWidget(widgetKey));
     }

     public async Task SaveWidget(Widget toBeSaved)
     {
          // Need both to be saved
          await Task.WhenAll(repo1.SaveWidget(toBeSaved), 
                             repo2.SaveWidget(toBeSaved));
     }

The above "combo" repository may well fulfil the needs of a single system (and there are many other ways to keep two databases synchronized).

CQRS is however frequently used at enterprise scale (i.e. where you have many systems, with many databases).

My comment about an Enterprise Service Bus will only make sense if you need to distribute data across an enterprise.

The concept is simple

  • Commands are queued to a transactional system (e.g. "Add Widget") across the bus.
  • Your system handling widgets performs the transaction (e.g. inserts the widget into a database)
  • The Widget system then publishes (broadcasts) a message to the bus detailing that a new widget has been added (with all the relevant widget information)
  • Other systems on in the enterprise which are interested in updates to Widgets subscribe to this message and will update their own Read Store representations of the Widgets (e.g. into a NoSql database or cache, and in the format which makes most sense to them).
  • This way, when a user accesses any of these other systems and views a screen about 'Widgets', the system can serve the data from its own Read Store, instead of having to request the data from the Widget system itself.
查看更多
登录 后发表回答