<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Udi Dahan - The Software Simplist &#187; CQRS</title>
	<atom:link href="http://www.udidahan.com/category/cqrs/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.udidahan.com</link>
	<description>Enterprise Development Expert &#38; SOA Specialist</description>
	<lastBuildDate>Sun, 08 Jan 2012 12:45:00 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Recording of joint interview with Eric Evans</title>
		<link>http://www.udidahan.com/2011/11/30/recording-of-joint-interview-with-eric-evans/</link>
		<comments>http://www.udidahan.com/2011/11/30/recording-of-joint-interview-with-eric-evans/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 04:59:14 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[CQRS]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Presentations]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1597</guid>
		<description><![CDATA[Last month both myself and Eric Evans spoke at a conference run by the International Association of Software Architects (IASA) in Madrid. Eric talked about DDD and I talked about CQRS. While the talks were recorded, I don&#8217;t think they&#8217;ve come online yet.
At the end of the conference, we were interviewed by the local .NET [...]]]></description>
			<content:encoded><![CDATA[<p>Last month both myself and Eric Evans spoke at a conference run by the International Association of Software Architects (IASA) in Madrid. Eric talked about DDD and I talked about CQRS. While the talks were recorded, I don&#8217;t think they&#8217;ve come online yet.</p>
<p>At the end of the conference, we were interviewed by the local .NET magazine dNM and that video is now available <a href="http://vimeo.com/32647895">here</a>. We covered the background on things like DDD, CQRS, and the Cloud. I don&#8217;t think that either of us said anything earth-shattering but if you have half an hour, take a look:</p>
<p><iframe src="http://player.vimeo.com/video/32647895?title=0&amp;byline=0&amp;portrait=0" width="400" height="225" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2011/11/30/recording-of-joint-interview-with-eric-evans/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why you should be using CQRS almost everywhere…</title>
		<link>http://www.udidahan.com/2011/10/02/why-you-should-be-using-cqrs-almost-everywhere%e2%80%a6/</link>
		<comments>http://www.udidahan.com/2011/10/02/why-you-should-be-using-cqrs-almost-everywhere%e2%80%a6/#comments</comments>
		<pubDate>Sun, 02 Oct 2011 20:45:44 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[CQRS]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[OO]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Simplicity]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1551</guid>
		<description><![CDATA[… but differently than the way most people have been using it.
I think I’ve just about drove everybody crazy now with my apparent zigzagging on CQRS.
Some people heard about CQRS first from one of my presentations and got all excited about it. Then I did some blogging which further drove people to CQRS (as did [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/grass.jpg" alt="grass" title="grass" width="200" height="150" style="float:right; margin-left:10px; margin-bottom:10px;" />… but differently than the way most people have been using it.</p>
<p>I think I’ve just about drove everybody crazy now with my apparent zigzagging on CQRS.</p>
<p>Some people heard about CQRS first from one of my presentations and got all excited about it. Then I did some blogging which further drove people to CQRS (as did Greg Young and some others). As CQRS was just about to hit its stride with the Early Adopters, I started pushing a more balanced view – CQRS not as an answer, but as one of many questions. More recently I’ve pushed more strongly back against CQRS saying that it should be used rarely.</p>
<h3>So what’s the missing piece?</h3>
<p>If you’re in the Domain-Driven Design camp (as many doing CQRS are), then it’s Bounded Contexts.</p>
<p>If you’re in the Event-Driven SOA camp (a much smaller camp to be sure), then it’s Services.</p>
<p>The problem is the naming, because the DDD guys have their kinds of services which do not fit the definition for Service of the Event-Driven SOA approach.</p>
<p>Let me propose the term Autonomous Business Component for the purposes of this blog post to describe that thing which is both a DDD Bounded Context (have the shared BC part of the acronym) and an SOA Autonomous Services. Resulting in the nice short form:  ABC (and everyone knows you need to have a good acronym if you want something to catch on).</p>
<h3>What does this have to do with CQRS?</h3>
<p>Nothing just yet. Well, at least, nothing directly to do with CQRS.</p>
<p>Although some proponents of CQRS have stated that it can and should be used as the top-most architectural pattern, both myself and Greg Young (arguably the first two to talk about it and the two who ultimately collaborated on naming it – and now Google knows we didn’t means “cars”) always recommended it as a pattern to be used one level down. </p>
<p>Although Greg and I have had many long discussions on the topic and do agree very much about what the overall structure should look like, I’ll try to avoid putting words in his mouth from this point on.</p>
<p>Before talking more about ABCs, let’s discuss the principle upon which they rest: The Single Responsibility Principle (SRP).</p>
<h3>What does SRP have to with CQRS?</h3>
<p>Many developers are familiar with SRP and have seen good results from using it. What we’re going to do is take this principle to the next level.</p>
<p>In Object Orientation (OO), data is encapsulated in an object. A good object does not expose its data to other objects to do with as they wish. Rather, it exposes methods that other objects can invoke, and those methods operate on the internal data.</p>
<p>SRP would guide us to not have the same data exist in two objects. For example, if we saw the customer’s first name as an internal data member of two objects, we’d be right to question that kind of duplication and move to refactor it away. However, when we see two systems doing the exact same thing – somehow that gets excused.</p>
<blockquote><p>“Of course we need to be able to see the customer’s first name in the front-end website as well as in the back-end fulfillment system. How could we NOT have the customer’s first name in both those code-bases?”</p></blockquote>
<p>And there’s the catch.</p>
<p>Who said that a system should be a single code-base?</p>
<h3>But what about integration?</h3>
<p>Although many times we do need to integrate existing systems together, sometimes we have the ability to change those systems. More importantly, when going to create a new solution, we can avoid getting ourselves into the problems that integration tries to solve.</p>
<p>Integrating with a system that cannot be changed can be done also by composing multiple ABCs, but that’s a topic for another post.</p>
<p>It is better to think of integration as a necessary evil – kind of like regular expressions and multi-threading; things to be avoided unless absolutely necessary.</p>
<p>“If you have a problem that you decide to use a regular expression to solve, you now have 2 problems.” Or so the saying goes. With multi-threading, you have a non-deterministic number of problems to solve.</p>
<p>If you thought you had duplicate responsibilities with 2 systems operating on the same data, how will introducing a 3rd code base (also known as “integration”) help? Remember that Single Responsibility Principle – our goal is to get it down to one.</p>
<h3>OK, so how do ABCs do that?</h3>
<p>In order for us to get back into alignment with SRP, that would require us to have responsibility for a single piece of data exist in one code base. Note that SRP makes no statements about how many physical places a given code base can be deployed to. Nor does it state that only a single technology can be in play – code that emits HTML can be packaged at design time together with rich-client code in the same solution.</p>
<p>If an ABC is responsible for a piece of data, it is responsible for it everywhere, and forever. No other ABC should see that data. That data should not travel between ABCs via remote procedure call (RPC) or via publish/subscribe. It is the ultimate level of encapsulation – SRP applied at the highest level of granularity.</p>
<p>This results in systems which are the result of deploying the components of multiple ABCs to the same physical place. The ABC which owns the customer name would have the necessary web code to render it in the e-commerce front-end and in the shipping back-end for printing on labels. This would mean that practically every screen in any UI is a composite of widgets owned by their respective ABCs.</p>
<p>This is ultimately what keeps the complexity of each ABC’s code base to a minimum. </p>
<h3>But why not just use CQRS as the top-level pattern? ABCs are weird.</h3>
<p>Imagine trying to create a single denormalized view model for the entire Amazon.com product page – product name, price, inventory, editorial review, customer comments, other products that customers viewed, other products that customers bought, etc. </p>
<p>Pretty complex, right?</p>
<p>How much duplication would you have for the page shown after you add an item to a cart? Once again, you need to show other products that customers bought, their names, images, prices, and inventory. </p>
<p>And then on the home page – items you might be interested in, names, images, prices.</p>
<p>And that’s only in the front-end system.</p>
<p>It’s not just the duplication, but how complex the code is for each one.</p>
<p>Instead of the duplication that top-level CQRS would bring you, consider an ABC responsible for products names and images that has just about the same view model composed on each of the above screens. The same with another ABC responsible for price.</p>
<p>You may be thinking that this would result in more queries to get the data to show on a page, and you’d be right. But it isn’t necessarily a classical N+1 Select problem, as the queries are bounded to the number of ABCs. Secondly, consider the ability to have well-tuned caching at the granularity of an ABC – something that would be much more difficult when dealing with everything as a single monolithic view model. In short, not only will it not be a performance problem, often it will actually improve performance.</p>
<h3>OK – that explains “everywhere”, what about “forever”?</h3>
<p>Forever is where things get interesting – or more accurately, when they get interesting.</p>
<p>Let’s talk about things like invoices.</p>
<p>One of the requirements in this area is that immutability. If the customer’s name was Jane Smith when they made their purchase, it doesn’t matter that they’ve since changed their name to Jane Jones, the invoice should still show Jane Smith.</p>
<p>Often developers push these types of requirements on the data warehouse guys – that’s where history gets handled. The only thing is that if your ABC owns the customer’s name, then no other code base can deal with it. If it’s your data, you have to handle all historical representations of it.</p>
<p>On the one hand, this would seem to kill the data warehouse. On the other hand, it means that the principles of data warehouses are now core to every code-base.</p>
<p>This means you don’t ever delete data (see my <a href="http://www.udidahan.com/2009/09/01/dont-delete-just-dont/">previous blog post</a> on the subject), and you definitely don’t overwrite it with an update – even if you think you’re in a simple CRUD domain. The only case where you can get away with traditional CRUD is if we’re talking about private data – data that is only ever acted on by a single actor.</p>
<h3>This sounds like the collaboration you talk about with CQRS</h3>
<p>It’s similar in principle but different in practice.</p>
<p>In a collaborative domain, an inherent property of the domain is that multiple actors operate in parallel on the same set of data. A reservation system for concerts would be a good example of a collaborative domain – everyone wants the “good seats” (although it might be better call that competitive rather than collaborative, it is effectively the same principle).</p>
<p>A customer’s name would not fall under that category. It isn’t an inherent property of the domain for multiple actors to operate on that data. While there can be multiple readers, one can easily enforce a single writer without any adverse effects. Doing that with a reservation system would cause the online system to behave as if users were lining up in front of a box office – not a desirable outcome.</p>
<p>Private data would be something like a user’s shopping cart. Until they make a purchase, that data doesn’t need to be visible anywhere. Here you could theoretically do simple CRUD – that is, until the business realizes that there’s extremely valuable information to be extracted from the historical record of things people do with their carts.</p>
<h3>I think you’re ready to make your point, so just make it already</h3>
<p>OK – so we now realize that Update and Delete don’t exist in their traditional form. Delete is really just a kind of update, and update is effectively an “upsert” – a combination of update and insert to retain history. This can be done by having ValidFrom and ValidTo columns for our data.</p>
<p>In which case, Create is really just a special case of Upsert, which looks like this:</p>
<blockquote><p>UPDATE Something SET ValidTo = NOW() WHERE Id=@Id AND ValidTo = NULL; INSERT INTO Something SET { regular values }, Id=@Id, ValidTo = NULL;</p></blockquote>
<p>And then we’d have 2 forms of Read – reading the current state (ValidTo = NULL), and reading history (ValidFrom <= Instant AND (ValidTo >= Instant OR ValidTo = NULL))</p>
<p>Here we don’t need fancy N-Tier architectures, data transfer objects, service layers, or domain models. A simple 2-Tier approach could probably suffice. We don’t need a task-based UI, events, denormalized view models, or any of that CQRS stuff. This was at the crux of my previous <a href="http://www.udidahan.com/2011/04/22/when-to-avoid-cqrs/">anti-CQRS post</a>.</p>
<p>The only thing is that this is exactly CQRS.</p>
<h3>Say what?</h3>
<p>Have we not effectively separated the responsibility of commands/upserts and queries/reads?</p>
<p>As Greg Young has said before, “the creation of 2 objects where there previously was one”.</p>
<p>Effectively 2 paths through our ABC.</p>
<p>CQRS.</p>
<p>Let me give you a second to gather your thoughts.</p>
<p>*</p>
<p>You see, CQRS is an approach, a mind-set – not a cookie cutter solution. Frameworks that guide you to applying CQRS exactly the same way everywhere are taking you in the wrong direction. The fact is that you couldn’t possibly know what your Aggregate Roots were before you figured out how to break your system down into ABCs. Attempting to create commands and events for everything will make you overcomplicate your solution.</p>
<h3>So the built-in history of this model is event-sourcing?</h3>
<p>Well, it’s not event-sourcing in the sense that we don’t necessarily have events. It achieves many of the benefits of event-sourcing by giving us the full history of what happened.</p>
<p>On the whole issue of replaying events to fix bugs – that’s a bit problematic, logically, unless we have a closed system. A closed system is one that doesn’t interact with anything else – no other systems, no users, nothing. As such, closed systems aren’t that common.</p>
<p>In an open system, one with users, let’s say there was a bug. This bug could have caused the wrong data to be written and/or shown to users. As such, users could have submitted subsequent commands based on that erroneous data that they would not have submitted otherwise. There’s no way for us to know.</p>
<p>The problem with replaying events when we fix the bug is that we’re in essence rewriting history – making it as if the user didn’t see the wrong data. The only problem is that we can’t know which events not to replay – we can’t automatically come up with the right events that should have come afterwards. We could try to sit together with our users and have them try to revise history manually, but our organization often isn’t in a bubble. Our users interacted with customers and suppliers. It isn’t feasible to try to undo the real-world impacts of this situation.</p>
<h3>Why didn’t you just tell us this from the very beginning?</h3>
<p>I did, you just weren’t listening.</p>
<p>You wanted a cookie cutter, and until you tried CQRS out as cookie cutter (and saw it create a bunch of complexity) you wouldn’t listen to anything else. </p>
<p>As developers, we’re trained to solve problems – the faster the better. Unfortunately, this causes us to be blind to things that don’t immediately present themselves as solutions.</p>
<p>When applying CQRS with ABCs, the solutions you end up with are very simple, but the process of getting there is quite hard and takes practice. Finding the boundaries of ABCs such that data isn’t duplicated between them and that data doesn’t travel between them either via RPC or publish/subscribe – it may feel impossible the first several times you try. Keep at it – it is almost always possible.</p>
<p>We haven’t touched on the whole saga/aggregate-root thing yet, but that isn’t as important until you can successfully apply the principles described here.</p>
<p>Also, this post has already gotten long enough, so it looks like now would be a good time to stop.</p>
<p>Until next time…</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2011/10/02/why-you-should-be-using-cqrs-almost-everywhere%e2%80%a6/feed/</wfw:commentRss>
		<slash:comments>47</slash:comments>
		</item>
		<item>
		<title>Inconsistent data, poor performance, or SOA &#8211; pick one</title>
		<link>http://www.udidahan.com/2011/09/18/inconsistent-data-poor-performance-or-soa-pick-one/</link>
		<comments>http://www.udidahan.com/2011/09/18/inconsistent-data-poor-performance-or-soa-pick-one/#comments</comments>
		<pubDate>Sun, 18 Sep 2011 16:52:17 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Autonomous Services]]></category>
		<category><![CDATA[Business Rules]]></category>
		<category><![CDATA[CQRS]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Data Access]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Reliability]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1527</guid>
		<description><![CDATA[One of the things that surprises some developers that I talk to is that you don&#8217;t always get consistency even with end-to-end synchronous communication and a single database. This goes beyond things like isolation levels that some developers are aware of and is particularly significant in multi-user collaborative domains.
The problem
Let&#8217;s start with an image to [...]]]></description>
			<content:encoded><![CDATA[<p>One of the things that surprises some developers that I talk to is that you don&#8217;t always get consistency even with end-to-end synchronous communication and a single database. This goes beyond things like isolation levels that some developers are aware of and is particularly significant in multi-user collaborative domains.</p>
<h3>The problem</h3>
<p>Let&#8217;s start with an image to describe the scenario:</p>
<p><img src="http://www.udidahan.com/wp-content/uploads/Inconsistency1.gif" alt="Inconsistency" title="Inconsistency" width="600" height="285" class="aligncenter size-full wp-image-1533" /><br />
<center>Image 1. 3 transactions working in parallel on 3 entities</center></p>
<p>The main issue we have here is that the values transaction 2 gets for A and B are those from T0 &#8211; before either transaction 1 or 3 completed. The reason this is an issue is that these old values (usually together with some message data) are used to calculate what the new state of C should be. </p>
<p>Traditional optimistic concurrency techniques won&#8217;t detect any problem if we don&#8217;t touch A or B in transaction 2.</p>
<p>In short, systems today are causing inconsistency.</p>
<h3>Some solutions</h3>
<p>1. Don&#8217;t have transactions which operate on multiple entities (which probably isn&#8217;t possible for some of your most important business logic).</p>
<p>2. Turn on <a href="http://en.wikipedia.org/wiki/Multiversion_concurrency_control">multi-version concurrency control</a> &#8211; this is called snapshot isolation in MS Sql Server.</p>
<p>Yes, you need to turn it on. It&#8217;s off by default.</p>
<p>The good news is that this will stop the writing of inconsistent data to your database.<br />
The bad news is that it will probably cause your system many more exceptions when going to persist.</p>
<p>For those of you who are using transaction messaging with automatic retrying, this will end up as &#8220;just&#8221; a performance problem (unless you follow the recommendations below). For those of you who are using regular web/wcf services (over tcp/http), you&#8217;re &#8220;cross cutting&#8221; exception management will likely end up discarding all the data submitted in those requests (but since that&#8217;s what you&#8217;re doing when you run into deadlocks this shouldn&#8217;t be news to you).</p>
<h3>The solution to the performance issues</h3>
<p>Eventual consistency.</p>
<p>Funny isn&#8217;t it &#8211; all those people who were afraid of eventual consistency got <b>inconsistency</b> instead.</p>
<p>Also, it&#8217;s not enough to just have eventual consistency (like between the command and query sides of CQRS). You need to drastically decrease the size of your entities. And the best way of doing that is to partition those entities across multiple business services (also known in DDD lingo as Bounded Contexts) each with its own database.</p>
<p>This is yet another reason why I say that CQRS shouldn&#8217;t be the top level architectural breakdown. Very useful within a given business service, yes &#8211; though sometimes as small as just some sagas.</p>
<h3>Next steps</h3>
<p>It may seem unusual that the title of this post implies that SOA is the solution, yet the content clearly states that traditional HTTP-based web services are a problem. Even REST wouldn&#8217;t change matters as it doesn&#8217;t influence how transactions are managed against a database.</p>
<p>The SOA solution I&#8217;m talking about here is the one I&#8217;ve spent the last several years <a href="http://www.udidahan.com/category/soa/">blogging about</a>. It&#8217;s a different style of SOA which has services stretch up to contain parts of the UI as well as down to contain parts of the database, resulting in a composite UI and multiple databases. This is a drastically different approach than much of the literature on the topic &#8211; especially Thomas Erl&#8217;s books.</p>
<p>Unfortunately there isn&#8217;t a book out there with all of this in it (that I&#8217;ve found), and I&#8217;m afraid that with my schedule (and family) writing a book is pretty much out of the question. Let&#8217;s face it &#8211; I&#8217;m barely finding time to blog.</p>
<p>The one thing I&#8217;m trying to do more of is provide training on these topics. I&#8217;ve just finished a course in London, doing another this week in Aarhus Denmark, and another next month in San Francisco (which is now sold out). The next openings this year will be in Stockholm, London; Sydney Australia and Austin Texas will be coming in January of next year. I&#8217;ll be coming over to the US more next year so if you missed San Francisco, keep an eye out.</p>
<p>I wish there was more I could do, but I&#8217;m only one guy.</p>
<p>Hmm, maybe it&#8217;s time to change that.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2011/09/18/inconsistent-data-poor-performance-or-soa-pick-one/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>When to avoid CQRS</title>
		<link>http://www.udidahan.com/2011/04/22/when-to-avoid-cqrs/</link>
		<comments>http://www.udidahan.com/2011/04/22/when-to-avoid-cqrs/#comments</comments>
		<pubDate>Fri, 22 Apr 2011 20:32:50 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[CQRS]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[Messaging]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Simplicity]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1441</guid>
		<description><![CDATA[It looks like that CQRS has finally &#8220;made it&#8221; as a full blown &#8220;best practice&#8221;.
Please accept my apologies for my part in the overly-complex software being created because of it.
I&#8217;ve tried to do what I could to provide a balanced view on the topic with posts like Clarified CQRS and Race Conditions Don&#8217;t Exist.
It looks [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/image20.png" alt="which way?" title="which way?" style="float:right; margin-left:10px; margin-bottom:10px;" />It looks like that CQRS has finally &#8220;made it&#8221; as a full blown &#8220;best practice&#8221;.</p>
<p>Please accept my apologies for my part in the overly-complex software being created because of it.</p>
<p>I&#8217;ve tried to do what I could to provide a balanced view on the topic with posts like <a href="http://www.udidahan.com/2009/12/09/clarified-cqrs/">Clarified CQRS</a> and <a href="http://www.udidahan.com/2010/08/31/race-conditions-dont-exist/">Race Conditions Don&#8217;t Exist</a>.</p>
<p>It looks like that wasn&#8217;t enough, so I&#8217;ll go right out and say it:</p>
<p>Most people using CQRS (and <a href="http://codebetter.com/gregyoung/2010/02/20/why-use-event-sourcing/">Event Sourcing</a> too) shouldn&#8217;t have done so.</p>
<h3>Should we really go back to N-Tier?</h3>
<p>When not using CQRS (which is the majority of the time), you don&#8217;t need N-Tier either.</p>
<p>You see, if you&#8217;re not in a collaborative domain then you don&#8217;t have multiple writers to the same logical set of data as an inherent property of your domain. As such, having a single database where all data lives isn&#8217;t really necessary. </p>
<p>Data is inherently partitioned by who owns it.</p>
<p>Let&#8217;s take the online shopping cart as an example. There aren&#8217;t any use cases where users operate on each others&#8217; carts &#8211; ergo, not collaborative, therefore not a good candidate for CQRS. Same goes for user profiles, and tons of other cases.</p>
<p>So why is it that we need a separate tier to run our business logic?</p>
<p>Originally, the application server tier was introduced for improved scalability, but specifically around managing the connection pool to the database. Increasing numbers of clients (when each had its own user/account for connecting to the database) caused problems. Luckily, most web applications side-step this problem &#8211; that is, until someone got the idea that the web server was only supposed to run the UI layer, and the Business Logic layer would be on a separate application server tier.</p>
<p>Rubbish &#8211; see Fowler&#8217;s First Law of Distribution: Don&#8217;t.</p>
<p>Keep it all on one tier. Same goes for smart clients.<br />
No, Silverlight, you don&#8217;t count &#8211; architecturally speaking, you&#8217;re a glorified browser.</p>
<h3>But what about scalability?</h3>
<p>In a non-collaborative domain, where you can horizontally add more database servers to support more users/requests/data at the same time you&#8217;re adding web servers &#8211; there is no real scalability problem (caveat, until you&#8217;re Amazon/Google/Facebook scale). </p>
<p>Database servers can be cheap &#8211; if using MySQL/SQL Express/others. </p>
<h3>But what about the built-in event-log CQRS/ES gives us?</h3>
<p>Architectural gold-plating / stealing from the business.</p>
<p>Who put you in a position to decide that development time and resources should be diverted from short-term business-value-adding features to support a non-functional requirement that the business didn&#8217;t ask for?</p>
<p>If you sat down with them, explaining the long-term value of having an archive of all actions in the system, and they said OK, build this into the system from the beginning, that would be fine. Most people who ask me about CQRS and/or Event Sourcing skip this step.</p>
<p>Finally, you can usually implement this specific requirement with some simple interception and logging. Don&#8217;t over-engineer the solution. If using messaging, you can get this by turning on journaling, or if you want to centralize this archive, NServiceBus can forward all messages to a specific queue. </p>
<p>Don&#8217;t forget that this storage has a cost &#8211; including administration. Nothing is free.</p>
<h3>What about the &#8220;proof of correctness&#8221; in Event Sourcing</h3>
<p>I&#8217;ve heard statements made that when you use the events that flowed into/through your system <b>AS</b> your system&#8217;s data, rather than transforming those events to some other schema (relational or otherwise) and storing the result &#8211; you can prove that your system behaves correctly.</p>
<p>Let me put it this way:</p>
<p>No programming technique used by humans will prevent those same humans from creating bugs.<br />
No testing technique used by humans will prevent those same humans from not catching those bugs.<br />
* Automated tests &#8211; see programming technique.</p>
<p>While having a full archive of all events can allow us to roll the system back to some state, fix a bug, and roll forwards, that assumes that we&#8217;re in a closed system. We have users which are outside the system. If a user made a decision based on data influenced by the bug, there&#8217;s no automated way for us to know that, or correct for it as we roll forwards.</p>
<p>In short, we&#8217;re interested in the business&#8217; behavior &#8211; as composed of user and system behavior. No proof can exist.</p>
<h3>Umm, so where should we use it</h3>
<p>If you&#8217;ve uncovered a scenario where you&#8217;re wondering &#8220;first-one-wins, or last-one-wins&#8221;, that&#8217;s often a good candidate for a place where CQRS <b>could</b> make sense. Then re-read my <a href="http://www.udidahan.com/2010/08/31/race-conditions-dont-exist/">Race Conditions Don&#8217;t Exist post</a>.</p>
<p>Also, CQRS should not be your top-level architectural pattern &#8211; that would be SOA.<br />
CQRS, if used at all, would be used inside a service boundary only.</p>
<p>Given that SOA guides us away from having a given 3rd normal form entity exist in any one service, it is unlikely that the building blocks of your CQRS design will be those kinds of entities. Most 3rd normal form one-to-many and many-to-many relationships simply do not exist when doing SOA and CQRS properly.</p>
<p>Therefore, I&#8217;m sorry to say that most sample application you&#8217;ll see online that show CQRS are architecturally wrong. I&#8217;d also be extremely wary of frameworks that guide you towards an entity-style aggregate root CQRS model.</p>
<h3>In Summary</h3>
<p>So, when should you avoid CQRS?</p>
<p>The answer is most of the time.</p>
<p>Here&#8217;s the strongest indication I can give you to know that you&#8217;re doing CQRS correctly: Your aggregate roots are sagas.</p>
<p>And the biggest caveat &#8211; the above are generalizations, and can&#8217;t necessarily be true for every specific scenario. If you&#8217;re Greg Young, then you probably can (and will) decide on your own on these matters. For everybody else, please take these warnings to heart. There have been far too many clients that have come to me all mixed up with their use CQRS in areas where it wasn&#8217;t warranted.</p>
<p>If you want to know everything you need to know to apply CQRS appropriately, please come to <a href="http://www.udidahan.com/training/#Advanced_Distributed_System_Design">my course</a> &#8211; there is so much unlearning to do first that just can&#8217;t happen via a series of blog posts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2011/04/22/when-to-avoid-cqrs/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>Race Conditions Don&#8217;t Exist</title>
		<link>http://www.udidahan.com/2010/08/31/race-conditions-dont-exist/</link>
		<comments>http://www.udidahan.com/2010/08/31/race-conditions-dont-exist/#comments</comments>
		<pubDate>Tue, 31 Aug 2010 09:56:46 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[BPM]]></category>
		<category><![CDATA[Business Rules]]></category>
		<category><![CDATA[CQRS]]></category>
		<category><![CDATA[NServiceBus]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[Workflow]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1335</guid>
		<description><![CDATA[Not in the business world anyway.
The problem is that, as software developers, we&#8217;re all too quick to accept them at face value. We don&#8217;t question the requirements &#8211; in all fairness, it was never our job to do so. We were the ones that implemented them, preferably quickly. 
For example
Let&#8217;s say we get the requirement [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/crossing-the-finish-line1.jpg" alt="crossing-the-finish-line" title="crossing-the-finish-line" width="200" height="159" style="float:right; margin-left:10px; margin-bottom:10px;"  />Not in the business world anyway.</p>
<p>The problem is that, as software developers, we&#8217;re all too quick to accept them at face value. We don&#8217;t question the requirements &#8211; in all fairness, it was never our job to do so. We were the ones that implemented them, preferably quickly. </p>
<h3>For example</h3>
<p>Let&#8217;s say we get the requirement the following requirements:</p>
<p>1. If the order was already shipped, don&#8217;t let the user cancel the order.<br />
2. If the order was already cancelled, don&#8217;t let the user ship the order.</p>
<p>The race condition here is when we have two users who are looking at the same order, which is neither cancelled nor shipped yet, and each submits a command &#8211; one to ship the order, the other to cancel it.</p>
<p>In these cases, the code is simple &#8211; just an if statement before performing the relevant command.</p>
<h3>So what&#8217;s the problem</h3>
<p>A microsecond difference in timing shouldn&#8217;t make a difference to core business behaviors. Which means that we&#8217;ve actually got here is a bug in the requirements. Users are actually dictating solutions here rather than requirements.</p>
<p>Let&#8217;s ask our stakeholders, &#8220;why shouldn&#8217;t we let users cancel a shipped order? I mean, the users don&#8217;t want the products.&#8221;</p>
<p>And the stakeholders would respond with something like, &#8220;well, we don&#8217;t want to refund the user&#8217;s money then. Or, at least, not all their money. Well, maybe if they return the products in their original packaging, *then* we could give a full refund.&#8221;</p>
<p>And as we drilled deeper, &#8220;when do refunds need to be given? Right away, in the same transaction?&#8221;</p>
<p>The stakeholders would explain, &#8220;no, refunds don&#8217;t need to be given right away.&#8221;</p>
<p>It turns out we were missing the concept of a refund, as well as assuming that all things needed to be processed and enforced immediately. Once we dug into the requirements, we found that there is actually plenty of time to allow both transactions to go through. We just need to add some checks during shipping&#8217;s long-running process to see if the order was cancelled, and then to cut the process short.</p>
<h3>So is everything a long-running process then?</h3>
<p>That&#8217;s actually a fair question &#8211; long-running processes are a lot more common than at first appears.</p>
<p>What we&#8217;re seeing is that cancellation is now a command that has no reason to fail &#8211; just like <a href="http://www.udidahan.com/2009/12/09/clarified-cqrs">CQRS</a> tells us. When this command is performed, it publishes the OrderCancelled event, which the billing service subscribes to. </p>
<p>Billing then starts a long-running process (a saga, in <a href="http://www.NServiceBus.com">NServiceBus</a> lingo), also listening to events from the shipping process, ultimately making a decision when a refund should be given, and for how much.</p>
<h3>Deeper business analysis</h3>
<p>As we discuss matters more with our business stakeholders, we hear that most orders are actually cancelled within an hour of being submitted. It is quite rare for orders to be cancelled days later.</p>
<p>In which case, we could look at modeling the acceptance of an order as a long-running process itself.</p>
<p>When a user places an order, we don&#8217;t immediately publish an event indicating the acceptance of an order, instead a saga is kicked off &#8211; which opens up a timeout for an hour later. If a cancellation command arrives during that period of time, the user gets a full refund (seeing as we didn&#8217;t charge anything since billing didn&#8217;t get the accepted event to begin with), and the saga just shuts itself down. If the timeout occurs an hour later, and the saga didn&#8217;t get a cancel command, then the order is actually accepted and the event is published.</p>
<p>Yes, sagas are everywhere, once you learn to see with business eyes, and no race conditions are left.</p>
<h3>In closing</h3>
<p>Any time you see requirements that indicate a race condition, dig deeper.</p>
<p>What you&#8217;re likely to find are some additional business concepts as well as the introduction of time and the creation of long-running business processes. The implementation at that point will pivot from being trivial if-statements to being richer sagas.</p>
<p>Keep an eye out.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2010/08/31/race-conditions-dont-exist/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>CQRS, DDD, and NServiceBus video</title>
		<link>http://www.udidahan.com/2010/06/18/cqrs-ddd-and-nservicebus-video/</link>
		<comments>http://www.udidahan.com/2010/06/18/cqrs-ddd-and-nservicebus-video/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 11:11:19 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[CQRS]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[NServiceBus]]></category>
		<category><![CDATA[Presentations]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1306</guid>
		<description><![CDATA[Following the theme of my last few blog posts, this post will also be pointing you to videos of me talking.
After I had finished speaking at QCon London last March, I sat down for a short interview with the guys from InfoQ chatting about topics from CQRS, to DDD, to NServiceBus. I&#8217;m happy to say [...]]]></description>
			<content:encoded><![CDATA[<p>Following the theme of my last few blog posts, this post will also be pointing you to videos of me talking.</p>
<p>After I had finished speaking at QCon London last March, I sat down for a short interview with the guys from InfoQ chatting about topics from CQRS, to DDD, to NServiceBus. I&#8217;m happy to say that the interview is now online with a full (and mostly accurate) transcript as well as with an MP3 download link.</p>
<p>Get it here: <a href="http://www.infoq.com/interviews/dahan-cqrs-ddd-nservicebus">Udi Dahan on CQRS, DDD and NServiceBus</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2010/06/18/cqrs-ddd-and-nservicebus-video/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CQRS isn&#8217;t the answer &#8211; it&#8217;s just one of the questions</title>
		<link>http://www.udidahan.com/2010/05/07/cqrs-isnt-the-answer-its-just-one-of-the-questions/</link>
		<comments>http://www.udidahan.com/2010/05/07/cqrs-isnt-the-answer-its-just-one-of-the-questions/#comments</comments>
		<pubDate>Fri, 07 May 2010 09:25:12 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[CQRS]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Simplicity]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1278</guid>
		<description><![CDATA[With the growing interest in Command/Query Responsibility Segregation (CQRS), more people are starting to ask questions about how to apply it to their applications. CQRS is actually in danger of reaching &#8220;best practice&#8221; status at which point in time people will apply it indiscriminately with truly terrible results. 
One of the things that I&#8217;ve been [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.udidahan.com/wp-content/uploads/dont_pan.gif" alt="dont panic" title="dont panic" width="260" height="180" style="float:right;" />With the growing interest in Command/Query Responsibility Segregation (<a href="http://www.udidahan.com/2009/12/09/clarified-cqrs/">CQRS</a>), more people are starting to ask questions about how to apply it to their applications. CQRS is actually in danger of reaching &#8220;best practice&#8221; status at which point in time people will apply it indiscriminately with truly terrible results. </p>
<p>One of the things that I&#8217;ve been trying to do with my presentations around the world on CQRS was to explain the <b>why</b> behind it, just as much as the what. The problem with the format of these presentations is that they&#8217;re designed to communicate a fairly closed message: here&#8217;s the problem, here&#8217;s how that problem manifests itself, here&#8217;s a solution.</p>
<p>In this post, I&#8217;m going to try to go deeper.</p>
<h3>The hitchhiker&#8217;s guide to the galaxy</h3>
<p>In this most excellent book, one of the things that struck me was the theme that made it&#8217;s way through the whole book &#8211; starting with the answer to life, the universe, and everything: 42. By the time you get to the end of the book, you find out that the real <b>question</b> to life, the universe, and everything is &#8220;what do you get when you multiply 6 by 9&#8243;. And that&#8217;s how the book leaves it.</p>
<p>To us engineers, we can&#8217;t just accept the fact that the book would say that 6*9 = 42 when we know it&#8217;s 54. After bashing our heads on the rigid rules of math, we realize that not all math problems are necessarily in base 10, and that if we switch to base 13, the number 42 is 4*13 + 2 = 54. So, the book was right &#8211; but that&#8217;s not the point.</p>
<h3>What&#8217;s the point?</h3>
<p>The hitchhiker&#8217;s guide is an example of a teaching technique which presents an apparent paradox, leaving the student to dig up unspoken and unthought assumptions in order to resolve it. Key to this technique are rigid rules which do not allow any compromise or shortcuts on the student&#8217;s part. </p>
<p>The purpose of this technique is not for the student to learn the answer, but to gain deeper understanding, which in turn changes the way they go about thinking about problems in the future. </p>
<p>So, when given the problem 4*5, we do not just immediately answer 20, instead we clarify in which numeric base the question is being phrased, and only then go to solve the problem. In base 13, the answer would be 17. In hex, the answer would be 14.</p>
<p>The externally visible change is that we know which questions to ask in order to arrive at the right answer &#8211; not that we know the answer ahead of time.</p>
<h3>Making an &#8220;ass&#8221; out of &#8220;u&#8221; and &#8220;me&#8221;</h3>
<p>Let&#8217;s start at the end &#8211; one of the unspoken assumptions that has been causing problems:</p>
<blockquote><p>
All businesses can be treated the same from the perspective of software.
</p></blockquote>
<p>In our previous example, we assumed that all math problems use base 10. It turns out that different bases are useful for different domains (like base 2 for computers). We can say similar things about degrees and radians in geometry. The more we look at the real world, the more we see this repeating itself. There&#8217;s no reason that software should be any different.</p>
<p>Base 10 is not a ubiquitous best practice. We shouldn&#8217;t be surprised that there really aren&#8217;t best practices for software either.</p>
<p>Here&#8217;s another problematic assumption:</p>
<blockquote><p>
&#8220;The business&#8221; can (and do) tell us what they need in a way we can understand.
</p></blockquote>
<p>So many software fads have been built on the quicksand of this assumption. OOAD &#8211; on verbs and nouns. 4GL and other visual tools that &#8220;the business&#8221; will use directly. SOA &#8211; on IT business alignment. I expect we haven&#8217;t seen the end of this.</p>
<p>Some of you may be wondering why this is false, others are sagely nodding their heads in agreement.</p>
<h3>The myth of &#8220;the business&#8221;</h3>
<p>Unless you have a single user, who is also the CEO paying for the development, there is no &#8220;the&#8221;. It&#8217;s an amalgam of people with different backgrounds, skills, and goals &#8211; there is no homogeneity. Even if no software was involved, many business organizations are dysfunctional with conflicting goals, policies, and politics.</p>
<p>To some extent, we technical people have hidden ourselves away in IT to avoid the scary world of business whose rules we don&#8217;t understand. With the rise in importance of information to the world, we&#8217;ve been pulled back &#8211; being forced to talk to people, and not just computers. Luckily, we&#8217;ve been able to create a buffer to insulate ourselves &#8211; we&#8217;ve taken the less successful technical people from our heard and nominated them &#8220;business analysts&#8221;. No, not all companies do it this way, but we do need to take a minute to reflect on how information flows between the business Mars into and out of the IT Venus.</p>
<h3>On human communication</h3>
<p>Even if we made this insulation layer more permeable, allowing and encouraging more technical people and business people to cross its boundary, we still need to deal with the problem of two humans communicating with each other. There are enough books that have been written on this topic, so I won&#8217;t go into that beyond recommending (strongly) to technical people to read (some of) them.</p>
<p>Rather, I&#8217;d like to focus on the environment in which these discussions take place. IT has been around long enough, and users have used computers long enough, that a certain amount of tainting has taken place. If the world was a trial, the evidence would have been thrown out as untrustworthy.</p>
<p>When users tell you what they want, they&#8217;re usually framing that with respect to the current system that they&#8217;re using. &#8220;Like the old system &#8211; but faster, and with better search, and more information on that screen, and&#8230;&#8221; </p>
<p>At this point, business analysts write down and formalize these &#8220;requirements&#8221; into some IT-sanctioned structure (use cases, user stories, whatever), at which point developers are told to build it. Users only know what they <b>didn&#8217;t</b> want when developers deliver exactly what was asked.</p>
<p>How can that be?</p>
<h3>These are not the &#8220;requirements&#8221; you are looking for</h3>
<p>Users ultimately dictate <b>solutions</b> to us, as a delta from the previous set of solutions we&#8217;ve delivered them. That&#8217;s just human psychology &#8211; writer&#8217;s block when looking at a blank page, as compared to the ease with which we provide &#8220;constructive criticism&#8221; on somebody else&#8217;s work.</p>
<p>We need to get the real requirements. We need to probe beyond the veneer:</p>
<ul>
<li>Why do you need this additional screen? </li>
<li>What real-world trigger will cause you to open it? </li>
<li>Is there more than one trigger? </li>
<li>How are they different?</li>
<li>etc, etc, etc&#8230;</li>
</ul>
<p>This is <b>real</b> work &#8211; different work than programming. It requires different skills. And that&#8217;s not even getting into the political navigation between competing organizational forces.</p>
<p>But let&#8217;s say that you don&#8217;t have (enough) people with these skills in your organization. What then?</p>
<h3>Enter CQRS</h3>
<p>CQRS gives us a set of questions to ask, and some rigid rules that our answers must conform to. If our answers don&#8217;t fit, we need to go back to the drawing board and move things around and/or go back to &#8220;the business&#8221; and seek deeper understanding there.</p>
<p>For each screen/task/piece of data:</p>
<blockquote><p>
Will multiple users be collaborating on data related to this task?<br />
Look at every shred of raw data, not just at the entity level.<br />
Are there business consistency requirements around groups of raw data?
</p></blockquote>
<p>If &#8220;the business&#8221; answers no &#8211; ask them if they see that answer changing, and if so, in what time frame, and why. What changing conditions in the business environment would cause that to change &#8211; what other parts of the system would need to be re-examined under those conditions.</p>
<p>After understanding all that and you find a true single-user-only-thing, then you can use standard &#8220;CRUD&#8221; techniques and technologies. There are no inherent time-propagation problems in a single-user environment &#8211; so eventual consistency is beyond pointless, it actually makes matters worse.</p>
<p>On the other hand, if the business-data-space is collaborative, the inherent time-propagation of information between actors means they will be making decisions on data that isn&#8217;t up-to-the-millisecond-accurate anyway. This is physics, gravity &#8211; you can&#8217;t fight it (and win).</p>
<h3>The rule for collaboration</h3>
<blockquote><p>
Actors must be able submit one-way commands that will fail only under exceptional <b>business</b> circumstances.
</p></blockquote>
<p>The challenge we have is how to achieve the real business objectives uncovered in our previous &#8220;requirements excavation&#8221; activities and follow this rule at the same time. This will likely involve a different user-system interaction than those implemented in the past. UI design is part of the solution domain &#8211; it shouldn&#8217;t be dictated by the business (otherwise it&#8217;s like someone asking you to run a marathon, but also dictating how you do so, like by tying your shoelaces together).</p>
<p>Many of the technical patterns I described in my <a href="http://www.udidahan.com/2009/12/09/clarified-cqrs/">previous blog post</a> describe the tools involved. BTW, hackers can be considered &#8220;exceptional actors&#8221; &#8211; the business actually wants their commands to fail.</p>
<h3>In Summary</h3>
<p>The hard and fast rule of CQRS about one-way commands is relevant for collaborative domains only. This domain has inherent eventual consistency &#8211; in the real world. Taking that and baking it into our solution domain is how we align with the business.</p>
<p>The process we go through, until ultimately arriving at one-way-almost-always-successful-commands <b>is business analysis</b>. Rejecting pre-formulated solutions, truly understanding the business drivers, and then representing those as directly as possible in our solution domain &#8211; that&#8217;s our job.</p>
<p>After doing this enough times and/or in more than one business domain, we may gain the insight that there is no cookie-cutter, one-size-fits-all, best-practice solution architecture for everything. Each problem domain is distinct and different &#8211; and we need to understand the details, because they <b>should</b> shape the resulting software structure.</p>
<p>The next time the business tell us to implement 42, we&#8217;ll use CQRS along with other questioning techniques until we can get &#8220;6 x 9&#8243; out of them, learning from the exercise what are the significant and stable parts of the business &#8211; ultimately helping us to &#8220;build the right system, and to build the system right&#8221;.</p>
<p>Don&#8217;t Panic <img src='http://www.udidahan.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2010/05/07/cqrs-isnt-the-answer-its-just-one-of-the-questions/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>CQRS Video Online</title>
		<link>http://www.udidahan.com/2010/02/26/cqrs-video-online/</link>
		<comments>http://www.udidahan.com/2010/02/26/cqrs-video-online/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 09:42:45 +0000</pubDate>
		<dc:creator>udidahan</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[CQRS]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Messaging]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Validation]]></category>

		<guid isPermaLink="false">http://www.udidahan.com/?p=1184</guid>
		<description><![CDATA[A couple of weeks ago I gave a talk on Command/Query Responsibility Segregation in London. 
The recording of the talk is online here.
There is one important thing that I didn&#8217;t have enough time to cover, but I want you to keep in mind as you&#8217;re watching this. It is that CQRS is applicable only *within* [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of weeks ago I gave a talk on Command/Query Responsibility Segregation in London. </p>
<p>The recording of the talk is online <a href="http://skillsmatter.com/podcast/open-source-dot-net/udi-dahan-command-query-responsibility-segregation/rl-311">here</a>.</p>
<p>There is one important thing that I didn&#8217;t have enough time to cover, but I want you to keep in mind as you&#8217;re watching this. It is that CQRS is applicable only *within* the context of a single service/BC &#8211; NOT across or between them.</p>
<p>Let me know what you think.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.udidahan.com/2010/02/26/cqrs-video-online/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
	</channel>
</rss>

