Several uart interrrupts can occur simultaneously. You need an ISR that reads the interrupt register and then handles all the cases based on the bits that are set. Besides Rx and Tx interrupts there are framing errors and maybe overflow errors.
To use interrupts successfully you will probably need an Rx queue, and a Tx queue. Your ISR will put into the RX queue, and the application will pull from it. The opposite for the Tx queue. Of course the application has to disable interrupts while it is operating on the queues.
Without queues, the application has to handle characters at the reception rate and is pretty much a slave to the RX interrupts. With a queue the application only has to keep up with the average character rate, which is usually substantially less than the maximum possible rate. The Rx queue has to be long enough to handle the maximum burst length expected
In my code there is the ISR and the two queues. Above that is a system task that interfaces to the queues and provides application funtionality like getchar(), gets(), putchar() and puts().