Well, it's a terrible design because you need to lock a row in KeyTable for the duration of your transaction against Table1. That is, while you're running the transaction:
- Fetch the value from KeyTable
- Store the incremented value in KeyTable
- Insert a new row in Table1
No concurrent session can be doing the same. This is a big penalty for scalability, because all your sessions that insert to Table1 are forced to queue up and access KeyTable serially.
Whereas any well-implemented identity feature should only need to lock the identity-allocator very briefly, improving throughput. This happens in memory. IDENTITY caches a set of the next 10 identity values, and sessions that insert rows draw from this set.
Using IDENTITY should reduce contention for locks on the storage engine level too, which would be required while writing the changes in KeyTable back to disk.