CRUD ਐਪਾਂ ਵਿੱਚ ਡੁਪਲੀਕੇਟ ਰਿਕਾਰਡ ਰੋਕਣ ਲਈ ਕਈ ਪੱਧਰ ਚਾਹੀਦੇ ਹਨ: ਡੇਟਾਬੇਸ ਯੂਨੀਕ ਕਨਸਟਰੇਂਟ, idempotency ਕੀਜ਼, ਅਤੇ UI ਹਾਲਤਾਂ ਜੋ ਦੂਜੀ ਸਬਮਿਸ਼ਨ ਨੂੰ ਰੋਕਦੀਆਂ ਹਨ।

ਡੁਪਲੀਕੇਟ ਰਿਕਾਰਡ ਉਹ ਹੁੰਦੇ ਹਨ ਜਦੋਂ ਤੁਹਾਡੀ ਐਪ ਇੱਕੋ ਚੀਜ਼ ਦੋ ਵਾਰੀ ਸਟੋਰ ਕਰ ਲੈਂਦੀ ਹੈ। ਇਹ ਇਕੋ ਚੈਕਆਊਟ ਲਈ ਦੋ ਆਰਡਰ ਹੋ ਸਕਦੇ ਹਨ, ਇਕੋ ਵੇਰਵੇ ਵਾਲੇ ਦੋ ਸਪੋਰਟ ਟਿਕਟ, ਜਾਂ ਇਕੋ ਸਾਈਨਅਪ ਫਲੋ ਤੋਂ ਦੋ ਅਕਾਊਂਟ। CRUD ਐਪ ਵਿੱਚ, ਡੁਪਲੀਕੇਟ ਆਮ ਤੌਰ 'ਤੇ ਅਲੱਗ-ਅਲੱਗ ਪੰਕਤੀਆਂ ਵਾਂਗ ਲੱਗਦੇ ਹਨ, ਪਰ ਜਦੋਂ ਤੁਸੀਂ ਸਾਰੀ ਡਾਟਾ ਵੇਖਦੇ ਹੋ ਤਾਂ ਇਹ ਗਲਤ ਹੁੰਦੇ ਹਨ।
ਜ਼ਿਆਦਾਤਰ ਡੁਪਲੀਕੇਟ ਸਧਾਰਣ ਵਰਤੋਂ ਤੋਂ ਸ਼ੁਰੂ ਹੁੰਦੇ ਹਨ। ਕੋਈ ਯੂਜ਼ਰ Create ਨੂੰ ਦੋ ਵਾਰੀ ਕਲਿੱਕ ਕਰ ਦਿੰਦਾ ਹੈ ਕਿਉਂਕਿ ਪੇਜ ਸੁਸਤ ਮਹਿਸੂਸ ਹੁੰਦਾ ਹੈ। ਮੋਬਾਈਲ 'ਤੇ ਡਬਲ ਟੈਪ ਆਸਾਨੀ ਨਾਲ ਹੋ ਸਕਦਾ ਹੈ। ਇੱਥੇ ਤੱਕ ਕਿ ਧਿਆਨ ਰੱਖਣ ਵਾਲੇ ਯੂਜ਼ਰ ਵੀ ਫਿਰ ਕੋਸ਼ਿਸ਼ ਕਰਦੇ ਹਨ ਜੇ ਬਟਨ ਅਜੇ ਵੀ ਐਕਟਿਵ ਦਿਖਦਾ ਹੈ ਅਤੇ ਕੋਈ ਵਾਜ਼ਿਬ ਸੰਕੇਤ ਨਹੀਂ ਹੁੰਦਾ ਕਿ ਕੁਝ ਹੋ ਰਿਹਾ ਹੈ।
ਫਿਰ ਹੈ ਗੰਦਲਾ ਵਿਚਕਾਰਲਾ ਹਿੱਸਾ: ਨੈੱਟਵਰਕ ਅਤੇ ਸਰਵਰ। ਇੱਕ ਰੀਕਵੇਸਟ timeout ਕਰ ਸਕਦੀ ਹੈ ਅਤੇ ਆਟੋਮੈਟਿਕ retry ਹੋ ਸਕਦੀ ਹੈ। ਇੱਕ ਕਲਾਇੰਟ ਲਾਇਬਰਾਰੀ POST ਨੂੰ ਦੁਹਰਾਉਂਦੀ ਹੈ ਜੇ ਇਹ ਸੋਚਦੀ ਹੈ ਕਿ ਪਹਿਲੀ ਕੋਸ਼ਿਸ਼ ਫੇਲ ਹੋ ਗਈ। ਪਹਿਲੀ ਰੀਕਵੇਸਟ ਸਫਲ ਹੋ ਸਕਦੀ ਹੈ, ਪਰ ਜਵਾਬ ਖੋ ਜਾ ਸਕਦਾ ਹੈ, ਤਾਂ ਯੂਜ਼ਰ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਦਾ ਹੈ ਅਤੇ ਦੂਜਾ ਨਾਂ ਕਾਪੀ ਬਣ ਜਾਂਦੀ ਹੈ।
ਤੁਸੀਂ ਇਹ ਸਿਰਫ ਇੱਕ ਪੱਧਰ 'ਤੇ ਨਹੀਂ ਸੁਧਾਰ ਸਕਦੇ ਕਿਉਂਕਿ ਹਰ ਪੱਧਰ ਸਿਰਫ਼ ਇੱਕ ਹਿੱਸਾ ਵੇਖਦਾ ਹੈ। UI ਦੂਹਰੀ ਸਬਮਿਟ ਘਟਾ ਸਕਦੀ ਹੈ, ਪਰ ਇਹ ਬੁਰੇ ਕਨੈਕਸ਼ਨ ਤੋਂ ਆ ਰਹੀਆਂ retries ਨੂੰ ਰੋਕ ਨਹੀਂ ਸਕਦੀ। ਸਰਵਰ ਮੁੜਹਾਰਾਂ ਦੀ ਪਹਚਾਣ ਕਰ ਸਕਦਾ ਹੈ, ਪਰ ਉਸਨੂੰ ਇਹ ਜਾਣਨ ਦਾ ਭਰੋਸੇਯੋਗ ਤਰੀਕਾ ਚਾਹੀਦਾ ਹੈ ਕਿ “ਇਹ ਪਹਿਲਾਂ ਹੀ ਬਣ ਚੁੱਕਾ ਹੈ।” ਡੇਟਾਬੇਸ ਨਿਯਮ ਲਗਾ ਸਕਦਾ ਹੈ, ਪਰ صرف ਜੇ ਤੁਸੀਂ ਪਰਭਾਵਸ਼ਾਲੀ ਤੌਰ 'ਤੇ ਪਰਿਭਾਸ਼ਿਤ ਕਰੋ ਕਿ “ਉਹੀ ਚੀਜ਼” ਦਾ ਕੀ مطلب ਹੈ।
ਮਕਸਦ ਸਾਦਾ ਹੈ: ਉਹਨਾਂ ਹਾਲਾਤਾਂ ਵਿੱਚ ਵੀ creates ਨੂੰ ਸੁਰੱਖਿਅਤ ਬਣਾਉਣਾ ਜਦੋਂ ਇੱਕੋ ਹੀ ਰੀਕਵੇਸਟ ਦੋ ਵਾਰੀ ਆ ਜਾਵੇ। ਦੂਜੀ ਕੋਸ਼ਿਸ਼ ਨੂੰ no-op, ਇੱਕ ਸਾਫ਼ “ਪਹਿਲਾਂ ਹੀ ਬਣ ਚੁੱਕਾ” ਜਵਾਬ, ਜਾਂ ਇੱਕ ਨਿਯੰਤ੍ਰਿਤ conflict ਬਣਨਾ ਚਾਹੀਦਾ ਹੈ — ਨ ਕਿ ਇੱਕ ਦੂਜੀ ਪੰਗਤੀ।
ਕਈ ਟੀਮਾਂ ਡੁਪਲੀਕੇਟ ਨੂੰ ਸਿਰਫ਼ ਡੇਟਾਬੇਸ ਦੀ ਸਮੱਸਿਆ ਮੰਨ ਲੈਂਦੀਆਂ ਹਨ। ਅਮਲ ਵਿੱਚ, ਡੁਪਲੀਕੇਟ ਅਕਸਰ ਉੱਥੇ ਹੀ ਪੈਦਾ ਹੁੰਦੇ ਹਨ ਜਦੋਂ ਇੱਕੋ create ਕਾਰਵਾਈ ਬਾਰ-ਬਾਰ ਟ੍ਰਿਗਰ ਹੋ ਜਾਵੇ।
ਕਿਸੇ ਯੂਜ਼ਰ ਨੇ Create ਕਲਿੱਕ ਕੀਤਾ ਅਤੇ ਕੁਝ ਹੋ ਰਹਿਆ ਹੋਇਆ ਨਹੀਂ ਲੱਗਦਾ, ਇਸ ਲਈ ਉਹ ਦੁਬਾਰਾ ਕਲਿੱਕ ਕਰ ਦਿੰਦਾ ਹੈ। ਜਾਂ ਉਹ Enter ਦਬਾਉਂਦਾ ਹੈ, ਫਿਰ ਤੁਰੰਤ ਬਟਨ ਕਲਿੱਕ ਕਰ ਦਿੰਦਾ ਹੈ। ਮੋਬਾਈਲ 'ਤੇ, ਦੋ ਤੇਜ਼ ਟੈਪ, ਟਚ ਅਤੇ ਕਲਿੱਕ ਇਵੈਂਟ ਦਾ ਓਵਰਲੈਪ, ਜਾਂ ਕੋਈ ਇਸ਼ਾਰਾ ਜੋ ਦੋ ਵਾਰੀ ਰਜਿਸਟਰ ਹੋ ਜਾਵੇ—ਇਹ ਸਭ ਮੁਮਕੀਨ ਹਨ।
ਹਾਲਾਂਕਿ ਯੂਜ਼ਰ ਸਿਰਫ਼ ਇੱਕ ਵਾਰੀ ਸਬਮਿਟ ਕਰਦਾ ਹੈ, ਨੈੱਟਵਰਕ ਫਿਰ ਵੀ ਰੀਕਵੇਸਟ ਦੋਹਰਾ ਸਕਦਾ ਹੈ। timeout retry ਨੂੰ ਟ੍ਰਿਗਰ ਕਰ ਸਕਦਾ ਹੈ। ਇੱਕ offline ਐਪ “Save” ਕਿਊ ਕਰ ਕੇ reconnect ਤੇ ਦੁਬਾਰਾ ਭੇਜ ਸਕਦੀ ਹੈ। ਕੁਝ HTTP ਲਾਇਬ੍ਰੇਰੀਆਂ ਕੁਝ errors 'ਤੇ ਆਟੋਮੈਟਿਕ retry ਕਰਦੀਆਂ ਹਨ, ਅਤੇ ਤੁਸੀਂ duplicate rows ਦੇਖਣ ਤੱਕ ਨੋਟਿਸ ਨਹੀਂ ਕਰਦੇ।
ਸਰਵਰ ਜਾਣ-ਬੂਝ ਕੇ ਕੰਮ ਦੁਹਰਾਉਂਦੇ ਹਨ। ਜੌਬ ਕਿਊਜ਼ failed jobs ਨੂੰ retry ਕਰਦੇ ਹਨ। webhook ਪ੍ਰੋਵਾਇਡਰ ਅਕਸਰ ਇੱਕੋ ਇਵੈਂਟ ਨੂੰ ਵੱਧ ਵਾਰੀ ਭੇਜਦੇ ਹਨ, ਖਾਸ ਕਰਕੇ ਜੇ ਤੁਹਾਡਾ endpoint धीरे ਚੱਲਦਾ ਹੈ ਜਾਂ non-2xx ਸਥਿਤੀ ਵਾਪਸ ਕਰਦਾ ਹੈ। ਜੇ ਤੁਹਾਡੀ create ਲਾਜਿਕ ਇਨ੍ਹਾਂ ਇਵੈਂਟਾਂ ਨਾਲ ਟ੍ਰਿਗਰ ਹੁੰਦੀ ਹੈ, ਤਾਂ ਧਾਰਨਾ ਕਰੋ ਕਿ duplicates ਹੋਣਗੇ।
ਕਨਕਰਨਸੀ ਸਭ ਤੋਂ ਛੁਪੇ ਹੋਏ duplicates ਬਣਾਉਂਦੀ ਹੈ। ਦੋ ਟੈਬਾਂ ਇਕੋ ਫਾਰਮ ਨੂੰ ਮਿਲੀ-ਪਹਿਲੀ ਮਿੰਟਾਂ ਵਿੱਚ ਸਬਮਿਟ ਕਰ ਸਕਦੀਆਂ ਹਨ। ਜੇ ਤੁਹਾਡਾ ਸਰਵਰ “ਹੈ ਕਿ ਨਹੀਂ?” ਚੈਕ ਕਰਦਾ ਹੈ ਅਤੇ ਫਿਰ ਇਨਸਰਟ ਕਰਦਾ ਹੈ, ਤਾਂ ਦੋਹਾਂ ਰੀਕਵੇਸਟਾਂ ਚੈਕ ਪਾਸ ਕਰ ਸਕਦੀਆਂ ਹਨ ਪਹਿਲਾਂ ਕਿ ਕੋਈ ਵੀ ਇਨਸਰਟ ਹੋਵੇ।
ਕਲਾਇੰਟ, ਨੈੱਟਵਰਕ, ਅਤੇ ਸਰਵਰ ਨੂੰ ਵੱਖ-ਵੱਖ ਦੁਹਰਾਉਂਦੇ ਸਰੋਤ ਸਮਝੋ। ਤੁਹਾਨੂੰ ਤਿੰਨੋ 'ਤੇ ਰੱਖਿਆ ਦੀ ਲੋੜ ਹੋਵੇਗੀ।
ਜੇ ਤੁਸੀਂ ਇੱਕ ਭਰੋਸੇਯੋਗ ਥਾਂ ਚਾਹੁੰਦੇ ਹੋ ਜਿੱਥੇ_duplicates_ ਨੂੰ ਰੋਕਿਆ ਜਾ ਸਕੇ, ਤਾਂ ਨਿਯਮ ਡੇਟਾਬੇਸ ਵਿੱਚ ਰੱਖੋ। UI ਸੁਧਾਰ ਅਤੇ ਸਰਵਰ ਜਾਂਚਾਂ ਮਦਦਗਾਰ ਹਨ, ਪਰ retries, ਲੈਗ ਜਾਂ ਇੱਕੋ ਸਮੇਂ ਦੋ ਯੂਜ਼ਰਾਂ ਦੀ ਕਾਰਵਾਈ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਉਹ ਫੇਲ ਹੋ ਸਕਦੇ ਹਨ। ਡੇਟਾਬੇਸ unique constraint ਆਖਰੀ ਅਥਾਰਟੀ ਹੈ।
ਪੇਹਲਾ ਕਦਮ ਇਹ ਹੈ ਕਿ ਇੱਕ ਅਸਲ-ਦੁਨੀਆ uniqueness ਨਿਯਮ ਚੁਣੋ ਜੋ ਲੋਕ ਕਿਵੇਂ ਸੋਚਦੇ ਹਨ ਉਸ ਨਾਲ ਮਿਲਦਾ ਹੋਵੇ। ਆਮ ਉਦਾਹਰਣ:
ਅਜਿਹੀਆਂ ਫੀਲਡਾਂ ਨਾਲ ਸਾਵਧਾਨ ਰਹੋ ਜੋ ਦਿਖਣ ਵਿੱਚ unique ਲੱਗਦੀਆਂ ਹਨ ਪਰ ਨਹੀਂ ਹੁੰਦੀਆਂ, ਜਿਵੇਂ ਪੂਰਾ ਨਾਮ।
ਜਦੋਂ ਤੁਹਾਡੇ ਕੋਲ ਨਿਯਮ ਹੋਵੇ, ਉਸਨੂੰ unique constraint (ਜਾਂ unique index) ਨਾਲ enforce ਕਰੋ। ਇਸ ਨਾਲ ਡੇਟਾਬੇਸ ਦੂਜੀ ਇਨਸਰਟ ਨੂੰ reject ਕਰ ਦੇਵੇਗਾ ਜੋ ਨਿਯਮ ਨੂੰ ਤੋੜਦੀ ਹੋਵੇ, ਭਾਵੇਂ ਦੋ ਰੀਕਵੇਸਟ ਇਕੋ ਸਮੇਂ ਆ ਰਹੀਆਂ ਹੋਣ।
ਜਦੋਂ constraint ਟ੍ਰਿਗਰ ਹੋਵੇ, ਤਾਂ ਸੋਚੋ ਕਿ ਯੂਜ਼ਰ ਨੂੰ ਕੀ ਦਿਖਾਇਆ ਜਾਵੇ। ਜੇ duplicate ਸਿਰਫ਼ ਗਲਤ ਹੈ, ਤਾਂ ਇਸਨੂੰ block ਕਰੋ ਅਤੇ ਇੱਕ ਸਾਫ਼ ਸੁਨੇਹਾ ਦਿਖਾਓ (“ਉਹ email ਪਹਿਲਾਂ ਹੀ ਵਰਤਿਆ ਜਾ ਚੁੱਕਾ ਹੈ”)। ਜੇ retries ਆਮ ਹਨ ਅਤੇ ਰਿਕਾਰਡ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ, ਤਾਂ ਅਕਸਰ retry ਨੂੰ success ਮੰਨ ਕੇ ਮੌਜੂਦਾ ਰਿਕਾਰਡ ਵਾਪਸ ਕਰਨਾ ਚੰਗਾ ਹੁੰਦਾ ਹੈ (“ਤੁਹਾਡਾ ਆਰਡਰ ਪਹਿਲਾਂ ਹੀ ਬਣਿਆ ਸੀ”)।
ਜੇ ਤੁਹਾਡਾ create ਅਸਲ ਵਿੱਚ “create ਜਾਂ reuse” ਹੈ, ਤਾਂ upsert ਸਭ ਤੋਂ ਸਾਫ਼ ਪੈਟਰਨ ਹੋ ਸਕਦਾ ਹੈ। ਉਦਾਹਰਣ: “email ਨਾਲ customer ਬਣਾਓ” ਨਵੀਂ ਪੰਗਤੀ ਇਨਸਰਟ ਕਰ ਸਕਦੀ ਹੈ ਜਾਂ ਮੌਜੂਦਾ ਨੂੰ ਵਾਪਸ ਕਰ ਸਕਦੀ ਹੈ। ਇਹ ਕੇਵਲ ਉਹਨਾਂ ਹਾਲਾਤਾਂ ਵਿੱਚ ਵਰਤੋ ਜਦੋਂ ਇਹ ਕਾਰੋਬਾਰੀ ਮਤਲਬ ਨਾਲ ਮੇਲ ਖਾਂਦਾ ਹੋਵੇ। ਜੇ ਥੋੜ੍ਹੇ ਵੱਖਰੇ payload ਇੱਕੋ key ਲਈ ਆ ਸਕਦੇ ਹਨ, ਤਾਂ ਫੈਸਲਾ ਕਰੋ ਕਿ ਕਿਹੜੇ ਖੇਤਰ update ਹੋਣਗੇ ਅਤੇ ਕਿਹੜੇ ਬਦਲੇ ਨਹੀਂ ਜਾ ਸਕਦੇ।
ਯੂਨੀਕ ਕਨਸਟਰੇਂਟ idempotency keys ਜਾਂ ਚੰਗੇ UI ਹਾਲਤਾਂ ਦੀ ਥਾਂ ਨਹੀਂ ਲੈਂਦੇ, ਪਰ ਉਹ ਇੱਕ ਕਠੋਰ ਰੋਕ ਦਿੰਦੇ ਹਨ ਜਿਸ ਤੇ ਬਾਕੀ ਸਾਰਾ ਸਿਸਟਮ ਆਧਾਰਿਤ ਰਹਿ ਸਕਦਾ ਹੈ।
ਇੱਕ idempotency ਕੀ ਇੱਕ ਵਿਲੱਖਣ ਟੋਕਨ ਹੁੰਦਾ ਹੈ ਜੋ ਇੱਕ ਯੂਜ਼ਰ ਦੀ ਨੀਅਤ ਨੂੰ ਦਰਸਾਂਦਾ ਹੈ, ਜਿਵੇਂ “ਇਹ ਆਰਡਰ ਇੱਕ ਵਾਰੀ ਬਣਾਓ।” ਜੇ ਇੱਕੋ ਰੀਕਵੇਸਟ ਮੁੜ ਭੇਜੀ ਜਾਂਦੀ ਹੈ (ਡਬਲ ਕਲਿੱਕ, ਨੈੱਟਵਰਕ retry, ਮੋਬਾਈਲ resume), ਤਾਂ ਸਰਵਰ ਇਸਨੂੰ ਇੱਕ retry ਵਜੋਂ ਲੈਂਦਾ ਹੈ, ਨ ਕਿ ਨਵੀਂ create ਵਜੋਂ।
ਇਹ ਉਹਨਾਂ ਟੂਲਾਂ ਵਿੱਚੋਂ ਇੱਕ ਸਭ ਤੋਂ ਬਹਿੈਦਿ ਹੈ ਜੋ create endpoints ਨੂੰ ਸੁਰੱਖਿਅਤ ਬਣਾਉਂਦਾ ਹੈ ਜਦੋਂ ਕਲਾਇੰਟ ਇਹ ਨਹੀਂ ਦੱਸ ਸਕਦਾ ਕਿ ਪਹਿਲੀ ਕੋਸ਼ਿਸ਼ ਸਫਲ ਹੋਈ ਜਾਂ ਨਹੀਂ।
ਜਿਹੜੇ endpoints ਸਭ ਤੋਂ ਜ਼ਿਆਦਾ ਲਾਭਾਨਵਿਤ ਹੁੰਦੇ ਹਨ ਉਹ ਹਨ ਜਿੱਥੇ duplicate ਮਹਿੰਗਾ ਜਾਂ ਗੁੰਝਲਦਾਰ ਹੋ ਸਕਦਾ ਹੈ—orders, invoices, payments, invites, subscriptions, ਅਤੇ forms ਜੋ emails ਜਾਂ webhooks ਨੂੰ ਟ੍ਰਿਗਰ ਕਰਦੇ ਹਨ।
ਰੀਟ੍ਰਾਈ 'ਤੇ, ਸਰਵਰ ਨੂੰ ਪਹਿਲੀ ਸਫਲ ਕੋਸ਼ਿਸ਼ ਦਾ ਮੂਲ ਨਤੀਜਾ ਵਾਪਸ ਕਰਨਾ ਚਾਹੀਦਾ ਹੈ, ਉਸੇ created record ID ਅਤੇ status code ਸਮੇਤ। ਇਹ ਕਰਨ ਲਈ, ਇੱਕ ਛੋਟਾ idempotency ਰਿਕਾਰਡ store ਕਰੋ ਜੋ (user ਜਾਂ account) + endpoint + idempotency key ਨਾਲ key ਕੀਤਾ ਹੋਵੇ। ਦੋਹਾਂ outcome (record ID, response body) ਅਤੇ ਇੱਕ “in progress” ਸਥਿਤੀ ਸੇਵ ਕਰੋ ਤਾਂ ਜੋ ਦੋ ਨੇੜਲੇ-ਸਮੇਂ ਵਾਲੀਆਂ ਰੀਕਵੇਸਟਾਂ ਦੋ ਰਿਕਾਰਡ ਨਾ ਬਣਾਉਣ।
idempotency ਰਿਕਾਰਡਾਂ ਨੂੰ ਇਨ੍ਹਾਂ retries ਨੂੰ cover ਕਰਨ ਲਈ ਕਾਫੀ ਸਮੇਂ ਲਈ ਰੱਖੋ। ਆਮ baseline 24 ਘੰਟੇ ਹੈ। payments ਲਈ ਕਈ ਟੀਮ 48–72 ਘੰਟੇ ਰੱਖਦੀਆਂ ਹਨ। TTL ਸਟੋਰੇਜ ਨੂੰ ਬਾਊਂਡ ਰੱਖਦੀ ਹੈ ਅਤੇ retry ਹੋਣ ਦੀ ਅਨੁਮਾਨਿਤ ਮਿਆਦ ਨਾਲ ਮੇਲ ਖਾਂਦੀ ਹੈ।
ਜੇ ਤੁਸੀਂ APIs ਕੋਈ chat-driven builder ਨਾਲ ਬਣਾਉਂਦੇ ਹੋ ਜਿਵੇਂ Koder.ai, ਫਿਰ ਵੀ idempotency ਨੂੰ ਜ਼ਾਹਰ ਕਰਨਾ ਚਾਹੀਦਾ ਹੈ: client-ਭੇਜੀ ਕੀ (header ਜਾਂ field) accept ਕਰੋ ਅਤੇ ਸਰਵਰ 'ਤੇ “same key, same result” enforce ਕਰੋ।
Idempotency ਇੱਕ create ਰੀਕਵੇਸਟ ਨੂੰ ਦੁਹਰਾਉਣਯੋਗ ਬਣਾਉਂਦਾ ਹੈ। ਜੇ ਕਲਾਇੰਟ timeout ਕਾਰਨ retry ਕਰਦਾ ਹੈ (ਜਾਂ ਯੂਜ਼ਰ ਦੋ ਵਾਰੀ ਕਲਿੱਕ ਕਰਦਾ ਹੈ), ਤਾਂ ਸਰਵਰ ਇੱਕੋ ਨਤੀਜਾ ਵਾਪਸ ਕਰਦਾ ਹੈ ਨਾ ਕਿ ਦੂਜੀ ਪੰਗਤੀ ਬਣਾਉਂਦਾ ਹੈ।
Idempotency-Key), ਪਰ JSON ਬਾਡੀ ਵਿੱਚ ਭੇਜਣਾ ਵੀ ਚਲ ਸਕਦਾ ਹੈ।ਮੁੱਖ ਗੱਲ ਇਹ ਹੈ ਕਿ “check + store” concurrency ਤਹਿਤ ਸੁਰੱਖਿਅਤ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ। ਅਮਲੀ ਤੌਰ 'ਤੇ, idempotency ਰਿਕਾਰਡ ਨੂੰ (scope, key) 'ਤੇ unique constraint ਨਾਲ ਸਟੋਰ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਅਤੇ conflicts ਨੂੰ reuse ਦੇ ਸਿਗਨਲ ਵਜੋਂ ਲਿਆ ਜਾਂਦਾ ਹੈ।
if idempotency_record exists for (user_id, key):
return saved_response
else:
begin transaction
create the row
save response under (user_id, key)
commit
return response
ਉਦਾਹਰਣ: ਇੱਕ ਗਾਹਕ “Create invoice” ਦਬਾਉਂਦਾ ਹੈ, ਐਪ key abc123 ਭੇਜਦੀ ਹੈ, ਅਤੇ ਸਰਵਰ invoice inv_1007 ਬਣਾਉਂਦਾ ਹੈ। ਜੇ ਫੋਨ ਸਿਗਨਲ ਗੁਆਚਕ ਕਰ ਦੇਵੇ ਅਤੇ retry ਭੇਜੇ, ਸਰਵਰ ਉਸੇ inv_1007 ਜਵਾਬ ਨਾਲ ਜਵਾਬ ਦੇਵੇਗਾ, ਨਾ ਕਿ inv_1008।
ਟੈਸਟ ਕਰਦਿਆਂ, ਸਿਰਫ਼ “double click” ਤੇ ਨਾ ਰੁਕੋ। ਇੱਕ ਅਜਿਹਾ ਸਿਮੂਲੇਟ ਕਰੋ ਜਿਸ 'ਚ ਕਲਾਇੰਟ 'ਤੇ ਰੀਕਵੇਸਟ timeout ਹੋ ਜਾਵੇ ਪਰ ਸਰਵਰ ਤੇ ਮੁਕੰਮਲ ਹੋ ਜਾਵੇ, ਫਿਰ ਉਹੀ ਕੀ ਨਾਲ retry ਕਰੋ।
ਸਰਵਰ-ਸਾਈਡ ਰੱਖਿਆ ਮਹੱਤਵਪੂਰਣ ਹੈ, ਪਰ ਬਹੁਤ ਸਾਰੇ duplicates ਆਮ ਤੌਰ 'ਤੇ ਮਨੁੱਖੀ ਕਾਰਵਾਈ ਦੇ ਦੌਰਾਨ ਹੁੰਦੇ ਹਨ। ਚੰਗੀ UI ਸੁਰੱਖਿਅਤ ਰਸਤਾ ਸਪੱਸ਼ਟ ਬਣਾਉਂਦੀ ਹੈ।
ਜਿਵੇਂ ਹੀ ਯੂਜ਼ਰ submit ਕਰੇ, submit ਬਟਨ ਨੂੰ disable ਕਰੋ। ਇਹ ਪਹਿਲੀ ਕਲਿੱਕ ਤੇ ਕਰੋ, ਨ ਕਿ validation ਤੋਂ ਬਾਅਦ ਜਾਂ ਰੀਕਵੇਸਟ ਸ਼ੁਰੂ ਹੋਣ 'ਤੇ। ਜੇ ਫਾਰਮ ਇੱਕੋ ਸਮੇਂ ਕਈ ਕੰਟਰੋਲਾਂ ਦੁਆਰਾ submit ਹੋ ਸਕਦਾ ਹੈ (ਬਟਨ ਅਤੇ Enter), ਤਾਂ ਸਾਰੀ ਫਾਰਮ ਸਥਿਤੀ ਲੌਕ ਕਰੋ, ਸਿਰਫ਼ ਇੱਕ ਬਟਨ ਨਹੀਂ।
ਇਹ ਪੁਛਦੇ ਹੋਏ ਇੱਕ ਸਪੱਸ਼ਟ progress state ਦਿਖਾਓ: ਕੀ ਇਹ ਚੱਲ ਰਿਹਾ ਹੈ? ਇੱਕ ਸਧਾਰਣ “Saving...” ਲੇਬਲ ਜਾਂ spinner ਕਾਫੀ ਹੁੰਦਾ ਹੈ। ਲੇਆਊਟ ਸਥਿਰ ਰੱਖੋ ਤਾਂ ਕਿ ਬਟਨ ਨਾ ਹਿਲੇ ਅਤੇ ਇਕ ਹੋਰ ਕਲਿੱਕ ਲਈ ਉਤਸ਼ਾਹ ਨਾ ਦਿਵਾਏ।
ਕੁਝ ਸਧਾਰਣ ਨਿਯਮ ਜ਼ਿਆਦਾਤਰ double submits ਰੋਕ ਦੇਂਦੇ ਹਨ: submit handler ਦੀ ਸ਼ੁਰੂਆਤ 'ਤੇ isSubmitting flag ਸੈੱਟ ਕਰੋ, ਜਦ ਤੱਕ ਇਹ true ਹੈ ਨਵੀਆਂ submits ਨੂੰ ਨਜ਼ਰਅੰਦਾਜ਼ ਕਰੋ (click ਅਤੇ Enter ਲਈ), ਅਤੇ ਇਹ ਸਿਰਫ਼ ਜਦ ਤੱਕ ਤੁਹਾਡੇ ਕੋਲ ਅਸਲੀ ਜਵਾਬ ਨਹੀਂ ਆ ਜਾਂਦਾ ਤਦ ਤਕ false ਨਾ ਕਰੋ।
ਧੀਰੇ ਜਵਾਬ ਉਹ ਥਾਂ ਹਨ ਜਿੱਥੇ ਬਹੁਤ ਸਾਰੀਆਂ ਐਪਾਂ slip ਹੁੰਦੀਆਂ ਹਨ। ਜੇ ਤੁਸੀਂ ਬਟਨ ਨੂੰ ਇੱਕ ਨਿਸ਼ਚਿਤ ਟਾਈਮਰ (ਉਦਾਹਰਣ 2 ਸਕਿੰਟ) ਤੋਂ ਬਾਅਦ ਮੁੜ enable ਕਰ ਦਿੰਦੇ ਹੋ, ਤਾਂ ਯੂਜ਼ਰ ਪਹਿਲੀ ਰੀਕਵੇਸਟ ਅਜੇ ਵੀ flight 'ਚ ਹੋਣ ਤੇ ਦੁਬਾਰਾ submit ਕਰ ਸਕਦਾ ਹੈ। ਕੇਵਲ ਉਸ ਵੇਲੇ ਰੀ-ਏਨੇਬਲ ਕਰੋ ਜਦੋਂ ਕੋਸ਼ਿਸ਼ ਮੁਕੰਮਲ ਹੋ ਜਾਵੇ।
ਸਫਲਤਾ ਤੋਂ ਬਾਅਦ, ਦੁਬਾਰਾ-submit ਦੀ ਸੰਭਾਵਨਾ ਘੱਟ ਕਰੋ। ਨਵਾਂ ਰਿਕਾਰਡ ਪੇਜ਼ ਜਾਂ ਲਿਸਟ 'ਤੇ ਨੈਵੀਗੇਟ ਕਰੋ ਜਾਂ ਇੱਕ ਸਾਫ਼ success state ਦਿਖਾਓ ਜਿਸ ਵਿੱਚ ਬਣਾਇਆ ਰਿਕਾਰਡ ਵਿਖਾਈ ਦੇਵੇ। ਇੱਕੋ ਹੀ ਭਰੇ ਹੋਏ ਫਾਰਮ ਨੂੰ ਸਕਰੀਨ 'ਤੇ ਛੱਡ ਕੇ ਬਟਨ ਨੂੰ ਐਨੇਬਲ ਨਾ ਛੱਡੋ।
ਟਿਕਾਊ duplicate ਬੱਗ ਆਮ “ਅਜਿਹਾ ਪਰ ਆਮ” ਵਰਤੋਂ-ਵਰਤੀ ਤਰੀਕਿਆਂ ਤੋਂ ਆਉਂਦੇ ਹਨ: ਦੋ ਟੈਬ, ਇੱਕ refresh, ਜਾਂ ਫੋਨ ਜੋ ਸਿਗਨਲ ਖੋ ਬੈਠਦਾ ਹੈ।
ਸਭ ਤੋਂ ਪਹਿਲਾਂ, uniqueness ਨੂੰ ਸਹੀ ਸਕੋਪ ਵਿੱਚ ਨਿਰਧਾਰਤ ਕਰੋ। “Unique” ਸ਼ਾਇਦ ਕਦੇ-ਕਦੇ “ਸਾਰੇ ਡੇਟਾਬੇਸ ਵਿੱਚ unique” ਦਾ ਮਤਲਬ ਨਹੀਂ ਹੁੰਦਾ। ਇਹ ਹੋ ਸਕਦਾ ਹੈ: ਪ੍ਰਤੀ ਯੂਜ਼ਰ, ਪ੍ਰਤੀ ਵਰਕਸਪੇਸ, ਜਾਂ ਪ੍ਰਤੀ ਟੈਨੈਂਟ। ਜੇ ਤੁਸੀਂ ਕਿਸੇ ਬਾਹਰੀ ਸਿਸਟਮ ਨਾਲ sync ਕਰ ਰਹੇ ਹੋ, ਤਾਂ ਤੁਹਾਨੂੰ ਉਹਨਾਂ ਬਾਹਰੀ ਸੂਤਰਾਂ ਲਈ uniqueness ਵੀ ਚਾਹੀਦੀ ਹੋ ਸਕਦੀ ਹੈ। ਇੱਕ ਸੁਰੱਖਿਅਤ ਅਪ੍ਰੋਚ ਇਹ ਹੈ ਕਿ ਤੁਸੀਂ ਉਹ ਸਹੀ ਵਾਕ ਲਿਖੋ ਜੋ ਤੁਸੀਂ ਮਤਲਬ ਰੱਖਦੇ ਹੋ (ਉਦਾਹਰਣ: “ਇੱਕ invoice ਨੰਬਰ ਪ੍ਰਤੀ ਟੈਨੈਂਟ ਪ੍ਰਤੀ ਸਾਲ”), ਫਿਰ ਉਸਨੂੰ enforce ਕਰੋ।
ਮਲਟੀ-ਟੈਬ ਵਰਤੋਂ ਇੱਕ ਕਲਾਸਿਕ ਚਤੁਰਾਈ ਹੈ। UI loading states ਇੱਕ ਟੈਬ 'ਚ ਮਦਦ ਕਰਦੇ ਹਨ, ਪਰ ਇਹ ਟੈਬਾਂ ਦੇ ਪਾਰ ਕੁਝ ਵੀ ਨਹੀਂ ਕਰਦੇ। ਇੱਥੇ ਸਰਵਰ-ਸਾਈਡ ਰੱਖਿਆ ਜ਼ਰੂਰੀ ਹੋਣੀ ਚਾਹੀਦੀ ਹੈ।
ਬੈਕ ਬਟਨ ਅਤੇ refresh ਅਕਸਰ ਗਲਤੀ ਨਾਲ ਮੁੜ-ਸਬਮਿਟ ਟ੍ਰਿਗਰ ਕਰਦੇ ਹਨ। ਸਫਲ create ਤੋਂ ਬਾਅਦ ਯੂਜ਼ਰ ਆਮ ਤੌਰ 'ਤੇ refresh ਕਰ ਕੇ “ਚੈੱਕ” ਕਰਦੇ ਹਨ, ਜਾਂ Back ਮਾਰ ਕੇ ਉਸੇ ਭਰਿਆ ਫਾਰਮ ਨੂੰ ਮੁੜ-ਸਬਮਿਟ ਕਰ ਦਿੰਦੇ ਹਨ। ਬਣਾਏ ਹੋਏ ਨਜ਼ਾਰੇ ਨੂੰ ਤਰਜੀਹ ਦਿਓ ਨਾ ਕਿ ਮੁਲ-ਫਾਰਮ ਨੂੰ, ਅਤੇ ਸਰਵਰ ਨੂੰ ਸੁਰੱਖਿਅਤ replays ਨੂੰ ਸੰਭਾਲਣਾ ਚਾਹੀਦਾ ਹੈ।
ਮੋਬਾਈਲ interruptions ਵੱਧ ਕਰ ਦਿੰਦੇ ਹਨ: backgrounding, flaky ਨੈੱਟਵਰਕ, ਅਤੇ ਆਟੋਮੈਟਿਕ retries। ਇੱਕ ਰੀਕਵੇਸਟ ਸਫਲ ਹੋ ਸਕਦੀ ਹੈ, ਪਰ ਐਪ ਨੂੰ ਜਵਾਬ ਨਹੀਂ ਮਿਲਦਾ, ਇਸ ਲਈ resume 'ਤੇ ਇਹ ਫਿਰ ਕੋਸ਼ਿਸ਼ ਕਰ ਸਕਦੀ ਹੈ।
ਸਭ ਤੋਂ ਆਮ ਨਾਕਾਮੀ ਦਾ ਤਰੀਕਾ UI ਨੂੰ ਹੀ ਇਕੱਲਾ ਗਾਰਡਰੇਲ ਮੰਨਣਾ ਹੈ। ਡਿਸੇਬਲ ਕੀਤਾ ਬਟਨ ਅਤੇ spinner ਮਦਦ ਕਰਦੇ ਹਨ, ਪਰ ਇਹ refreshes, flaky ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ, ਦੂਜਾ ਟੈਬ, ਜਾਂ ਕਲਾਇੰਟ ਬੱਗ ਨੂੰ ਕਵਰ ਨਹੀਂ ਕਰਦੇ। ਸਰਵਰ ਅਤੇ ਡੇਟਾਬੇਸ ਨੂੰ ਵੀ ਇਹ ਕਹਿਣਾ ਹੋਵੇਗਾ ਕਿ “ਇਹ create ਪਹਿਲਾਂ ਹੀ ਹੋ ਚੁੱਕੀ ਹੈ।”
ਇੱਕ ਹੋਰ ਫੰਦਾ ਗਲਤ ਫੀਲਡ ਨੂੰ uniqueness ਲਈ ਚੁਣਨਾ ਹੈ। ਜੇ ਤੁਸੀਂ ਕੁਝ ਜੋ ਅਸਲ ਵਿੱਚ unique ਨਹੀਂ ਹੈ (ਜਿਵੇਂ last name, rounded timestamp, free-form title) 'ਤੇ unique constraint ਲਾਓਗੇ ਤਾਂ ਤੁਸੀਂ ਵੈਧ ਰਿਕਾਰਡਾਂ ਨੂੰ ਰੋਕ ਦਿਓਗੇ। ਬਦਲੇ ਵਿੱਚ, ਇੱਕ ਅਸਲ ID (ਜਿਵੇਂ external provider ID) ਵਰਤੋ ਜਾਂ scoped rule (unique per user, per day, ਜਾਂ per parent record) ਵਰਗੀਆਂ ਨੀਤੀਆਂ ਲਗਾਓ।
Idempotency keys ਵੀ ਗਲਤ ਤਰੀਕੇ ਨਾਲ ਅਸਾਨੀ ਨਾਲ ਲਾਗੂ ਹੋ ਸਕਦੀਆਂ ਹਨ। ਜੇ ਕਲਾਇੰਟ ਹਰ retry 'ਤੇ ਨਵੀਂ key ਜਨਰੇਟ ਕਰਦਾ ਹੈ, ਤਾਂ ਹਰ ਵਾਰੀ ਨਵਾਂ create ਮਿਲੇਗਾ। ਉਸੇ ਉਦੇਸ਼ ਲਈ ਪਹਿਲੀ ਕਲੀਕ ਤੋਂ ਲੈ ਕੇ ਸਾਰੀਆਂ retries ਤੱਕ ਇੱਕੋ key ਵਰਤੋ।
ਇਕ ਹੋਰ ਧਿਆਨ ਵਾਲੀ ਗੱਲ ਇਹ ਹੈ ਕਿ ਤੁਸੀਂ retries 'ਤੇ ਕੀ ਵਾਪਸ ਕਰਦੇ ਹੋ। ਜੇ ਪਹਿਲੀ ਰੀਕਵੇਸਟ ਨੇ ਰਿਕਾਰਡ ਬਣਾਇਆ ਸੀ, ਤਾਂ retry ਨੂੰ ਉਹੀ ਨਤੀਜਾ (ਜਾਂ ਘੱਟੋ-ਘੱਟ ਉਹੀ record ID) ਵਾਪਸ ਕਰਨੀ ਚਾਹੀਦੀ ਹੈ—ਕਿਸੇ ਅਸਪਸ਼ਟ error ਨਾਲ ਯੂਜ਼ਰ ਨੂੰ ਫਿਰ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਪ੍ਰੇਰਿਤ ਨਾ ਕਰੋ।
ਜੇ ਇੱਕ unique constraint duplicate ਨੂੰ ਰੋਕਦੀ ਹੈ, ਤਾਂ ਇਹ ਗਲਤ ਨਤੀਜੇ ਦੇ ਕੇ “ਕੁਝ ਗਲਤ ਹੋ ਗਿਆ” ਨਾ ਕਹਿਣ। ਸਪਸ਼ਟ ਬੋਲੋ: “ਇਹ invoice ਨੰਬਰ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ। ਅਸੀਂ ਪਹਿਲੀ ਨੂੰ ਰੱਖਿਆ ਅਤੇ ਦੂਜੀ ਨਹੀਂ ਬਣਾਈ।”
ਰਿਲੀਜ਼ ਤੋਂ ਪਹਿਲਾਂ duplicate creation paths ਲਈ ਇੱਕ ਛੋਟਾ ਪਾਸ ਕਰੋ। ਸਭ ਤੋਂ ਵਧੀਆ ਨਤੀਜੇ ਵੱਖ-ਵੱਖ ਰੱਖਿਆਵਾਂ ਦੇ ਜੋੜ ਨਾਲ ਆਉਂਦੇ ਹਨ ਤਾਂ ਜੋ ਇੱਕ ਛੁੱਟੀ ਹੋਈ ਕਲਿੱਕ, retry, ਜਾਂ ਧੀਮਾ ਨੈੱਟਵਰਕ ਵੀ ਦੋ ਪੰਗਤੀਆਂ ਨਹੀਂ ਬਣਣ ਦੇਵੇ।
ਤਿੰਨ ਗੱਲਾਂ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ:
ਇੱਕ ਪ੍ਰੈਕਟਿਕਲ ਗਟ ਚੈਕ: ਫਾਰਮ ਖੋਲੋ, ਤੇਜ਼ੀ ਨਾਲ ਦੋ ਵਾਰੀ submit ਕਲਿੱਕ ਕਰੋ, ਫਿਰ mid-submit refresh ਕਰੋ ਅਤੇ ਫਿਰ ਕੋਸ਼ਿਸ਼ ਕਰੋ। ਜੇ ਤੁਸੀਂ ਦੋ ਰਿਕਾਰਡ ਬਣਾਉ ਸਕਦੇ ਹੋ, ਤਾਂ ਅਸਲ ਯੂਜ਼ਰ ਵੀ ਕਰ ਲੈਂਗੇ।
ਇਕ ਛੋਟੀ invoice ਐਪ ਦੀ ਕਲਪਨਾ ਕਰੋ। ਯੂਜ਼ਰ ਨਵਾਂ invoice ਭਰਦਾ ਹੈ ਅਤੇ Create 'ਤੇ ਟੈਪ ਕਰਦਾ ਹੈ। ਨੈੱਟਵਰਕ ਸੁਸਤ ਹੈ, ਸਕਰੀਨ ਤੁਰੰਤ ਨਹੀਂ ਬਦਲਦੀ, ਅਤੇ ਉਹ ਫਿਰ Create ਟੈਪ ਕਰ ਦਿੰਦਾ ਹੈ।
ਕੇਵਲ UI ਰੱਖਿਆ ਨਾਲ, ਤੁਸੀਂ ਬਟਨ disable ਕਰ ਸਕਦੇ ਹੋ ਅਤੇ spinner ਦਿਖਾ ਸਕਦੇ ਹੋ। ਇਹ ਮਦਦ ਕਰਦਾ ਹੈ, ਪਰ ਇਹ ਕਾਫ਼ੀ ਨਹੀਂ ਹੈ। ਕੁਝ ਡਿਵਾਈਸਾਂ 'ਤੇ double tap ਫਿਰ ਵੀ ਨਿਬ ingredient ਸਕਦਾ ਹੈ, timeout ਤੋ ਬਾਅਦ retry ਹੋ ਸਕਦਾ ਹੈ, ਜਾਂ ਦੋ ਟੈਬ ਤੋਂ submit ਹੋ ਸਕਦਾ ਹੈ।
ਕੇਵਲ ਡੇਟਾਬੇਸ unique constraint ਨਾਲ, ਤੁਸੀਂ ਬਿਲਕੁਲ ਮਿਲਦੇ-ਜੁਲਦੇ duplicates ਨੂੰ ਰੋਕ ਸਕਦੇ ਹੋ, ਪਰ ਅਨੁਭਵ ਕੁਝ ਕਰਦੇ ਹੋਏ ਕਠੋਰ ਹੋ ਸਕਦਾ ਹੈ। ਪਹਿਲੀ ਰੀਕਵੇਸਟ ਸਫਲ ਹੋਈ, ਦੂਜੀ constraint ਨਾਲ ਟਕਰਾਏਗੀ, ਅਤੇ ਯੂਜ਼ਰ ਨੂੰ error ਦਿਖਾਈ ਦੇਵੇਗਾ ਹਾਲਾਂਕਿ invoice ਬਣ ਚੁੱਕੀ ਸੀ।
ਸੁਥਰਾ ਨਤੀਜਾ idempotency ਅਤੇ unique constraint ਦੋਹਾਂ ਨਾਲ ਮਿਲ ਕੇ ਆਉਂਦਾ ਹੈ:
ਦੂਜੀ ਟੈਪ ਤੋਂ ਬਾਅਦ ਇੱਕ ਸਧਾਰਣ UI ਸੁਨੇਹਾ: “Invoice created - ਅਸੀਂ ਦੂਜੀ ਸਬਮਿਸ਼ਨ ਨੂੰ ਨਜ਼ਰਅੰਦਾਜ਼ ਕੀਤਾ ਅਤੇ ਪਹਿਲੀ request ਨੂੰ ਰੱਖਿਆ।”
ਇੱਕ ਬਿਸਤਰੀਕ ਨੀਵ ਰੱਖਣ ਤੋਂ ਬਾਅਦ, ਅਗਲੇ ਫਾਇਦੇ ਵਿਪੁਲਤਾ, cleanup, ਅਤੇ ਏਕਰੂਪਤਾ ਬਾਰੇ ਹੁੰਦੇ ਹਨ।
create paths 'ਤੇ ਹਲਕੀ-ਫੁਲਕੀ logging ਸ਼ਾਮਿਲ ਕਰੋ ਤਾਂ ਤੁਸੀਂ ਅਸਲ ਯੂਜ਼ਰ ਕਾਰਵਾਈ ਅਤੇ retry ਵਿੱਚ ਫਰਕ ਬਖ਼ੂਬੀ ਦੇਖ ਸਕੋ। idempotency key, ਸ਼ਾਮਿਲ unique fields, ਅਤੇ outcome (created vs returned existing vs rejected) ਲੌਗ ਕਰੋ। ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਤੁਹਾਨੂੰ ਭਾਰੀ tooling ਦੀ ਲੋੜ ਨਹੀਂ।
ਜੇ duplicates ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹਨ, ਤਾਂ ਇੱਕ ਸਾਫ਼ ਨਿਯਮ ਅਤੇ ਆਡਿਟ ਟਰੇਲ ਨਾਲ ਉਹਨਾਂ ਨੂੰ ਸਾਫ਼ ਕਰੋ। ਉਦਾਹਰਣ: ਸਭ ਤੋਂ ਪੁਰਾਣੇ ਰਿਕਾਰਡ ਨੂੰ “ਵਿਨਰ” ਰੱਖੋ, ਸੰਬੰਧਿਤ ਰੋਜ਼ (payments, line items) ਨੂੰ ਉਹਦੇ ਨਾਲ ਜੋੜੋ, ਅਤੇ ਹੋਰਾਂ ਨੂੰ merged ਵਜੋਂ ਨਿਸ਼ਾਨ ਲਗਾਓ ਬਜਾਏ ਹਟਾਉਣ ਦੇ। ਇਸ ਨਾਲ support ਅਤੇ ਰਿਪੋਰਟਿੰਗ ਆਸਾਨ ਹੋ ਜਾਂਦੀ ਹੈ।
ਆਪਣੇ uniqueness ਅਤੇ idempotency ਨਿਯਮ ਇੱਕ ਜਗ੍ਹਾ ਲਿਖ ਕੇ ਰੱਖੋ: ਕੀ unique ਹੈ ਅਤੇ ਕਿਸ ਸਕੋਪ ਵਿੱਚ, idempotency keys ਕਿੰਨਾ ਲੰਬਾ ਰੱਖਣੇ, errors ਕਿਵੇਂ ਦਿਖਣਗੇ, ਅਤੇ UI retries 'ਤੇ ਕੀ ਕਰੇਗਾ। ਇਸ ਨਾਲ ਨਵੇਂ endpoints safety rails ਬਾਈਪਾਸ ਨਹੀਂ ਕਰਨਗੇ।
ਜੇ ਤੁਸੀਂ CRUD ਸਕ੍ਰੀਨਜ਼ ਤੇਜ਼ੀ ਨਾਲ Koder.ai (koder.ai) ਵਿੱਚ ਬਣਾਉਂਦੇ ਹੋ, ਤਾਂ ਇਹ ਚੰਗਾ ਹੈ ਕਿ ਇਹ ਵਰਤੂਏਂ default ਟੈਮਪਲੇਟ ਵਿੱਚ ਸ਼ਾਮਿਲ ਹੋਣ: schema ਵਿੱਚ unique constraints, API ਵਿੱਚ idempotent create endpoints, ਅਤੇ UI ਵਿੱਚ ਸਪਸ਼ਟ loading states। ਇਸ ਤਰ੍ਹਾਂ ਤੇਜ਼ੀ messy ਡੇਟਾ ਦਾ ਕਾਰਨ ਨਹੀਂ ਬਣਦੀ।
ਇੱਕ ਡੁਪਲੀਕੇਟ ਰਿਕਾਰਡ ਉਹ ਹੁੰਦਾ ਹੈ ਜਦੋਂ ਇੱਕੋ ਹੀ ਅਸਲੀ ਚੀਜ਼ ਦੋ ਵਾਰ ਸੰਗ੍ਰਹਿਅਤ ਹੋ ਜਾਵੇ—ਜੈਸੇ ਇੱਕ ਚੈਕਆਉਟ ਲਈ ਦੋ ਆਰਡਰ ਜਾਂ ਇਕੋ ਮੁੱਦੇ ਲਈ ਦੋ ਟਿਕਟ। ਆਮ ਤੌਰ 'ਤੇ ਇਹ ਇਸ ਕਰਕੇ ਹੁੰਦਾ ਹੈ ਕਿ ਇੱਕੋ “create” ਕਾਰਵਾਈ ਬਾਰ-ਬਾਰ ਚੱਲ ਜਾਂਦੀ ਹੈ—ਵੂਜ਼ਰ ਦੁਹਰਾਅ, ਰੀਟ੍ਰਾਈ, ਜਾਂ concurrency ਕਾਰਨ।
ਕਿਉਂਕਿ ਦੂਜੀ ਗ੍ਰਹਿਣਾ ਬਿਨਾਂ ਯੂਜ਼ਰ ਦੇ ਪਤਾ ਲੱਗੇ ਹੋ ਸਕਦੀ ਹੈ: ਮੋਬਾਈਲ 'ਤੇ ਡਬਲ ਟੈਪ, Enter ਦਬਾਉਣ ਤੇ ਫਿਰ ਬਟਨ ਕਲਿਕ, ਜਾਂ ਕਲਾਇੰਟ/ਨੈੱਟਵਰਕ/ਸਰਵਰ ਵੱਲੋਂ ਆਟੋਮੈਟਿਕ ਰੀਟ੍ਰਾਈ। ਸਰਵਰ ਨੂੰ ਇਹ ਧਿਆਨ ਵਿੱਚ ਰੱਖਣਾ ਚਾਹੀਦਾ ਹੈ ਕਿ “POST = ਇੱਕ ਵਾਰੀ” ਨਹੀਂ ਮੰਨਿਆ ਜਾ ਸਕਦਾ।
ਨਹੀਂ—ਇਹ ਅਕਸਰ ਕਾਫ਼ੀ ਨਹੀਂ ਹੁੰਦਾ। ਬਟਨ ਨੂੰ ਡਿਸੇਬਲ ਕਰਨਾ ਅਤੇ “Saving…” ਦਿਖਾਉਣਾ ਇਸ ਨੂੰ ਘਟਾਉਂਦਾ ਹੈ, ਪਰ flaky ਨੈੱਟਵਰਕ, ਰੀਫਰੈਸ਼, ਕਈ ਟੈਬ, ਬੈਕਗ੍ਰਾਊਂਡ ਵਰਕਰ ਜਾਂ webhook redeliveries ਨੂੰ ਨਹੀਂ ਰੋਕਦਾ। ਸਰਵਰ ਅਤੇ ਡੇਟਾਬੇਸ ਦੀਆਂ ਰੱਖਿਆਵਾਂ ਵੀ ਲਾਜ਼ਮੀ ਹਨ।
ਯੂਨੀਕ ਕਨਸਟਰੇਂਟ ਉਹ ਫੀਲਡ ਹੋਣੀ ਚਾਹੀਦੀ ਹੈ ਜੋ ਅਸਲੀ ਦੁਨੀਆ ਵਿੱਚ ਅਨੁਕੂਲ ਹੁੰਦੀ ਹੈ ਅਤੇ ਅਕਸਰ ਸਕੋਪ ਕੀਤੀ ਜਾਂਦੀ ਹੈ (ਪ੍ਰਤੀ tenant, ਪ੍ਰਤੀ ਵਰਕਸਪੇਸ ਆਦਿ)। ਡੇਟਾਬੇਸ ਵਿੱਚ ਇਹ ਨਿਯਮ ਰੱਖੋ ਤਾਂ ਦੋ ਬਦਲਦੇ ਤੱਕੜੇ ਆਏ ਤਾਂ ਵੀ ਦੂਜੀ ਇਨਸਰਟ ਰੋਕ ਦਿੱਤੀ ਜਾਵੇਗੀ।
ਦੋਹਾਂ ਦੀ ਲੋੜ ਹੈ। ਯੂਨੀਕ ਕਨਸਟਰੇਂਟ ਫੀਲਡ-ਅਧਾਰਿਤ ਨਕਲਾਂ ਨੂੰ ਰੋਕਦੇ ਹਨ (ਜਿਵੇਂ invoice number), ਜਦਕਿ idempotency ਕੀ ਇੱਕ ਖਾਸ create ਕੋਸ਼ਿਸ਼ ਨੂੰ ਦੁਹਰਾਉਣਯੋਗ ਬਣਾਉਂਦੀ ਹੈ (ਇੱਕੋ ਕੀ ਆਏ ਤਾਂ ਇੱਕੋ ਨਤੀਜਾ)। ਦੋਹਾਂ ਨਾਲ ਤੁਹਾਨੂੰ ਸੁਰੱਖਿਆ ਅਤੇ ਚੰਗਾ ਯੂਜ਼ਰ ਐਕਸਪੇਰੀਅੰਸ ਮਿਲਦਾ ਹੈ।
ਹਰ ਵਰਤੋਂਕਾਰ ਦੀ niyat (ਉਦੇਸ਼) ਲਈ ਇੱਕ ਕੀ ਬਣਾਓ—ਉਦਾਹਰਣ: “Create” ਦਬਾਉਣ ਤੇ ਇਕ ਕੀ। ਉਸੇ ਕੀ ਨੂੰ ਉਸੇ ਉਦੇਸ਼ ਲਈ ਹੋਣ ਵਾਲੀਆਂ ਸਾਰੀ retries ਵਿੱਚ ਦੁਹਰਾਓ ਅਤੇ ਰੀਕਵੇਸਟ ਨਾਲ ਭੇਜੋ। ਕੀ timeout ਜਾਂ app resume ਤੋਂ ਬਾਅਦ ਵੀ ਸਥਿਰ ਰਹੇ ਪਰ ਭਿੰਨ create ਲਈ ਮੁੜ ਵਰਤੋਂ ਨਾ ਹੋਵੇ।
ਇੱਕ idempotency ਰਿਕਾਰਡ ਸਟੋਰ ਕਰੋ ਜੋ(scope: user/ account) + endpoint + idempotency key ਤੇ ਉਸ ਰਿਕਾਰਡ ਕੀਤੇ ਨਤੀਜੇ (record ID, response body) ਨੂੰ ਸੇਵ ਕਰੇ। ਜੇ ਉਹੀ ਕੀ ਫਿਰ ਆਵੇ ਤਾਂ ਸੇਵ ਕੀਤੀ ਗਈ ਜਵਾਬੀayload ਵਾਪਸ ਦਿਓ—ਨਵਾਂ ਰਿਕਾਰਡ ਨਹੀਂ ਬਣਾਉ।
“ਚੈੱਕ + ਸਟੋਰ” concurrency-safe ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ—ਅਕਸਰ idempotency ਰਿਕਾਰਡ 'ਤੇ (scope, key) ਦਾ unique constraint ਰੱਖ ਕੇ। ਇਸ ਤਰ੍ਹਾਂ ਦੋ ਨੇੜਲੇ ਸਮੇਂ ਵਾਲੀਆਂ ਰੀਕਵੇਸਟਾਂ ਦੋਾਰਾ ਦੋ ਰਿਕਾਰਡ ਬਣਨ ਤੋਂ ਰੁਕ ਜਾਂਦੀਆਂ ਹਨ—ਇੱਕ ਨੂੰ conflicts ਦਿਖਣਗੇ ਅਤੇ ਉਹ ਸਟੋਰ ਕੀਤੇ ਨਤੀਜੇ ਨੂੰ ਰੀਯੂਜ਼ ਕਰੇਗਾ।
ਉਹਨਾਂ ਰੀਟ੍ਰਾਈਜ਼ ਲਈ ਕਾਫੀ ਲੰਬੇ ਸਮੇਂ ਤਕ ਰੱਖੋ; ਆਮ ਤੌਰ 'ਤੇ 24 ਘੰਟੇ ਇੱਕ ਵਧੀਆ ਬੇਸਲਾਈਨ ਹੈ। payments ਵਰਗੀ flows ਲਈ 48–72 ਘੰਟੇ ਵੀ ਰੱਖਣ ਦੀ ਲੋੜ ਹੋ ਸਕਦੀ ਹੈ। TTL ਨਾਲ ਸਟੋਰੇਜ ਬਾਊਂਡ ਕਰ ਦਿਉ ਅਤੇ retry ਸੰਭਾਵਨਾ ਨਾਲ ਮੈਚ ਕਰੋ।
ਜਦੋਂ duplicate ਸਹੀ ਤੌਰ 'ਤੇ ਇੱਕੋ ਉਦੇਸ਼ ਦਾ ਦੁਹਰਾਉ ਹੁੰਦਾ ਹੈ ਤਾਂ ਉਸਨੂੰ ਇੱਕ successful retry ਵਜੋਂ ਵਰਤੋ ਅਤੇ ਪਹਿਲੀ ਬਣੀ ਹੋਈ record (ਉਹੀ ID) ਵਾਪਸ ਕਰੋ। ਜੇ record ਸੱਚਮੁਚ unique ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ (ਜਿਵੇਂ email), ਤਾਂ ਸਾਫ਼ conflict ਸੁਨੇਹਾ ਦਿਓ ਜੋ ਦੱਸੇ ਕਿ ਕੀ ਹੋਇਆ।