A transaction ensures "atomicity" of a unit of work. That means either it all succeeds or everything is reset to the point it was before the unit started. A bank transfer is a good example. To transfer money from account A to account B, you subtract money from account A and add the same amount to account B. This work may fail at any point. Assume it fails after the balance of A is reduced, but before the balance of B is increased. The money disappears! In this case, we must somehow reset the balance of A to what it was before the transfer, i.e., before the start of the transaction.
Fortunately, databases let us make temporary changes, then either commit them to make them permanent, or roll them back to erase them. However, when one transaction uses multiple databases (or other resources), we need a resource manager, like what an application server provides. This manager supports two-phase commit (not two-phase transactions). In phase one, the manager asks each resource if it's OK to commit the changes. If every single one of them says it's OK, then phase two is the manager issuing the commit command to all resources. If any resource says it can't commit, then the manager commands all resources to rollback.
It's actually a fairly simple concept, but tricky to implement. That's why we're lucky the app server vendors have already done it for us!