To me abstraction rarely has to do with technical issues alone. When writing a layer of abstraction the domain plays a huge role. I find this specific issue is often handled badly with ORM's. A relational database especially is rarely modeled in a way that reflects domain behaviors. I therefore cringe when I see ORM's used to generate a object mirror of the database schema. Unless it's a pure CRUD app what do we really gain by doing this? Other than database intellisense.
Greg Young threw me a bit of when for some time ago I mentioned using Unit of Work and he replied “why do you need that?”. I frankly didn't even understand the question. Why would I not need a Unit of Work? I now know the answer and it makes me sad. I never knew what an aggregate was about and frankly I never really paid attention to the problem I was trying to solve. I never included the domain into the actual solution.
When doing something like generating an object version of a relational database we state that “I have no idea what this thing is supposed to do so I'll support everything”.Instead of first getting an understanding of the domain behaviors and create a persistence model supporting those scenarios.
Back to what Greg said. Why don't we need a Unit of Work? Because we have modeled true behaviors. Unit of Work is solving transactional issues. Actually Unit of Work is there to handle transactions between aggregates. The reason we tend to use a Unit of Work is because we have paid no attention to what an aggregate should contain. If we have an object model that is generated from a database schema our aggregates are defined by our database relations. Because of that our aggregates are completely separated from our domain behaviors. Resulting in most domain behaviors touching more than one aggregate. And through that we are forced to use a Unit of Work. However if we take the time to model our aggregates based on actual behavior there would be no need for cross aggregate transactions. Actually what we are doing when not paying attention to domain behaviors is creating and impedance mismatch between the problem we are trying to solve and our technical implementation.