How to get statement which causes error 3609?
If you use TRY/CATCH in the calling code and trigger, then the error handling process becomes a lot more predictable and reliable.

Without this, an error in the trigger (here caused by RAISERROR) aborts the batch. So you'll never see the error from RAISERROR.

See Why TRY CATCH does not suppress exception in trigger for more

Note: a trigger is always in a transaction because it is part of the DML. Any trigger code/actions must be atomic with the DML of course.