7

I have a 3-tier architecture that looks roughly like this:

Client -> Business -> Data

Where should transactions ideally start?

One school of thought says that transactions should only start at the top of the Data layer. The Business layer only manipulates business objects with business logic, and never knows about transactions. The business does all of its work to manipulate objects, and then hands them to the Data layer to be persisted. It's a somewhat RESTful philosophy applied to lower layers.

Another school of thought says that transactions should start at the top of the Business layer. The Business layer defines logical units of work, not the data layer, because a logical unit of work sometimes contains business logic, not just data logic.

I do like the idea of pushing transaction concerns as low as possible. But I also find it can require extra effort and design challenges to try and keep business logic out of the data layer, unless it's just CRUD operations. If you apply RESTful design patterns with a sledgehammer, you can make it so that your applications have very few non-CRUD operations.

There is even a 3rd school of thought that says that the Client could start transactions so that it can combine multiple business operations when it needs to. But now the Client is defining the unit-of-work? Isn't that a business concern?

A 4th school of thought says that my Clients can be just SOA components that could participate in an XA transaction started even outside the client!!

Our developers would like some standards more concrete than just "Start transactions wherever you feel like"

Does anyone have any opinions or suggestions on this subject?

Thanks!

techuser soma
  • 4,766
  • 5
  • 23
  • 43
Beaker
  • 744
  • 7
  • 18
  • FWIW, Java EE starts transactions with the Session Beans, which is effectively the Business layer. (But Java EE often makes design choices that favor integration at the expense of decoupling) – Beaker Apr 17 '13 at 16:30

2 Answers2

3

Transaction is a business concept and it should be coordinated from within the Business Tier.

Manipulating objects in isolation usually makes little benefit and spanning the manipulation between multiple types of objects already is a transaction. So first school of thought is dealing with really basic cases.

When your Business Tier is handling transactions it doesn't really matter who starts the transaction: client or other service. Also long running (distributed) transactions can only be supported when Business Tier is aware of them.

Kimi
  • 13,621
  • 9
  • 55
  • 84
2

In the

Client -> Business -> Data

architecture, it is always better to define the transaction on the business layer. I would suggest that the transaction be so defined that the business service either starts a new transaction or participates in the existing transaction if one is already started. This takes care of cases where a business service is invoked by another business service.

Having the transaction boundary at the data layer fails if the business layer make multiple data layer calls as part of the same request, as

client1-> business1 => data1 , business1 => data2

techuser soma
  • 4,766
  • 5
  • 23
  • 43
  • The counter argument is that you could refactor to do never need to call two different data methods from the business method. This assumes your business methods are very limited in scope themselves. I don't fully agree with this argument, but I've seen a RESTful design pattern applied with such enthusiasm that it really did drive 99% of cross-domain complexity out of an application. Was it worth it? Not sure. :) – Beaker Apr 17 '13 at 18:08
  • "refactor to do never need to call two different data methods" in any of the services is a very ideal thought. In my opinion, for such a case not much planning is required around transaction. In the data layer methods just make a connection.setautocommit("false") at the start of the method and then set it back to true or rollback in the finally block. Applications and db relations are seldom that simple. – techuser soma Apr 17 '13 at 20:01