Any method that includes locking in the assigned number to prevent duplicates runs the risk of creating gaps if the record is not committed. This is exactly what Access does with autonumbers. It assignes the number and commits it immediately. Then if the record is not completed, a gap is created because the record is discarded.
The issue is nothing to do with locking. Any technique that allocates a number and then allows the user to cancel the record will result in gaps.
As I said previously, what matters is when the number is generated relative to when the record is saved. If another number is allocated before the record is saved then it will be prone to duplication.
If you have to have a sequence number that increments by 1 and has no gaps, you need to assign the number yourself and you need to use a loop that increments the sequence number if it duplicates an existing value and try the insert again and again until you succeed. That is the only way to guarantee no gaps.
The part about having to assign the number yourself is correct. However the technique described is certainly not the only way to achieve no gaps.
The technique I described also works reliably. The number needs to be allocated immediately before the record is committed and no other users allowed to get the next number until that process is completed.
This is easily achieved by opening a recordset against the NextNumber table with dbDenyRead + dbDenyWrite Options argument. The recordset is closed after the value is read, incremented and the record saved. In this case a loop repeatedly trys to open the recordset in case another user already had it locked.
In my opinion this is considerably better than what I see as a clumsy solution of capturing the errors resulting from attempting to write a duplicate key and looping until it works as you have described.
During conflicts your technique would result in far more network traffic and processing by the engine.
Moreover I regard error capture (especially errors raised by the database engine or server) as the very last resort to dealing with logical requirements.