The actual transaction takes 3 seconds but it does not really time out after 2 seconds. The ejb container compares the actual time take (3 seconds in this case) with the set time (2 seconds) and then throws the TransactionTimeoutException.
Can I catch the TransactionTimeoutException after 2 seconds? Thx.
I doubt you'll ever hit exactly, but how far off you are will depend on the reason for the timeout. If the timeout is due to some kind of blocking I/O (which you aren't supposed to do inside an EJB, but could still be an issue for a container service implementation used by the EJB), then you might not see the transaction failure until the block ends. I've definitely found that to be true for Weblogic.
Transaction timeouts unfortunately don't provide soft realtime-like guarantees, they just do the best they can. Sometimes you are better off moving some code interaction to JMS/MDB or JCA or JMX, depending on the problem, to improve your control over timing.