XACT_ABORT ON not working as expected on SQL Server 2012?
Check Microsoft documentation, specifically the top line:
The THROW statement honors SET XACT_ABORT. RAISERROR does not. New applications should use THROW instead of RAISERROR.
I believe that is your problem, right there.
https://msdn.microsoft.com/en-us/library/ms188792.aspx