I have always worked on projects where caching was done on DAL, basically just when you are about to make the call to database, it checks if data is already there in the cache and if it is, it just doesn’t make the call and instead returns that data.
I just recently read about caching at business layer, so basically caching the entire business objects. One advantage I can see straight away is much better response times.
When would you prefer one over the other? and Is caching at Business Layer a common practice?
3
This is probably too broad for a definitive answer.
Personally, I feel that a data access layer is the better place for caching, simply because it is supposed to be very simple – records go in and out and that’s it.
A business layer implements many additional rules of higher complexity, so it’s better if it doesn’t also have to manage per-object availability concerns in addition to multiple-object consistency concerns in the same class(or even the same method) – that would be a blatant violation of the SRP.
(Of course, I only reached that insight after my service classes had grown to unmanageable complexity when they tried to do both caching and configuration simultaneously. There is no better teacher than experience, but the price sure is steep.)
1
Data access and persistence/storage layers are irresistibly natural places for caching. They’re doing the I/Os, making them handy, easy place to insert caching. I daresay that almost every DAL or persistence layer will, as it matures, be given a caching function–if it isn’t designed that way from the very start.
The problem is intent. DAL and persistence layers deal with relatively low-level constructs–for example, records, tables, rows, and blocks. They don’t see the “business” or application-layer objects, or have much insight into how they’re being used at higher levels. When they see a handful of rows or a dozen blocks being read or written, it’s not clear that they represent. “The Jones account we’re currently analyzing” doesn’t look much different from “some basic taxation rate reference data the app needs just once, and to which it won’t refer again.” At this layer, data is data is data.
Caching at the DAL/persistence layer risk having the “cold” tax reference data sitting there, pointlessly occupying 12.2MB of cache and displacing some account information that will, in fact, be intensively used in just a minute. Even the best cache managers are dealing with scant knowledge of the higher level data structures and connections, and little insight as to what operations are coming soon, so they fall back to guesstimation algorithms.
In contrast, application- or business-layer caching isn’t nearly so neat. It requires inserting cache management operations or hints in the middle of other business logic, which makes the business code more complex. But the tradeoff is: Having more knowledge of how macro-level data is structured and what operations are coming up, it has a much better opportunity to approximate optimal (“clairvoyant” or “Bélády Min”) caching efficiency.
Whether inserting cache management responsibility into business/application code makes sense is a judgment call, and will vary by applications. In many cases, while it’s known that DAL/persistence layers won’t get it “perfectly right,” the tradeoff is that they can do a pretty good job, that they do so in an architecturally “clean” and much more intensively testable way, and that low-level catching avoids increasing the complexity of business/app code.
Lower complexity encourages higher correctness and reliability, and faster time-to-market. That is often considered a great tradeoff–less perfect caching, but better-quality, more timely business code.
7
Caching on the DAL is straightforward and simple
Your DAL is the central data access layer, which means that any and all data access can be controlled through the classes there. As both reading and persisting happens on those layers it is equally easy to clear or update cache entries as changes happen.
Caching in the business is flexible
Caching on the business gives developers the flexibility to determine if the concrete usage of an object will benefit from caching. Depending on the structure of the application back-end services or automated processes might change data that is cached in other parts. With caching in the business a developer can determine if a certain business object will have possible stale data and gain performance, or have the most up-to-date state of a business object at the expense of performance.