Uploads are processed asynchronously by concurrent workers. On any upload the user can allocate a tag, the keys should also be tagged. This combination dramatically increases the probability of two processes trying to create a tag at the same time. If uniqueness validation is enabled, Rails will look for existing records before performing Tag. If a record was found the validation fails and the transaction will be rolled back, if not the record will be saved. Example of how Rails validation fails:.
The increase of the number and the complexity of hooks, will also lead to an increased probability of the creation of non unique records. I18n Manager for Global Success Learn how to find the best i18n manager and follow our best practices for making your business a global success. The solution in preventing the creation non unique records would therefore be setting up a unique database index.
To make this index unique multiple without downtime, these steps are needed:. Adding a unique index to a table which contains non unique entries will raise an exception. Therefore, we will need to cleanup the database before adding the index. If new duplicated entries are introduced between the cleanup and the adding of the index, the migration will fail.
So we first have to make sure that no new duplicated records can be created. You can solve this by using temporary tables, but we chose another approach. The default value of this column should be NULL. Validation helpers are one of those things that make me feel warm and cozy when deploying a new app out in the wild. This provides a lot of support for a large range of data you may be collecting from the client-side.
Each helper accepts a :on and :message option. There are a ton of validation helpers, below are some of my most used. Please check out the guide on active record validations for more use-cases. Useful for validating when two text fields need to have the same entry. Think of an email confirmation for example. One gotcha here is that this validation only performs if the presence option is set to true in the model as well.
If you need to reserve any words or make sure a given entry is unique use exclusion. Notice how I used :message here as well. This is provided on all validation helpers. Formatting strings are sometimes ideal for your app. You can use regular expressions within validations to alter whatever you're after. Feel free to personalize the messages with :message here as well.
The following are all available to hook into to customize the message. This is probably the most widely used helper in my tool bag. Presence checks that fields are not empty. This actually searches the User table for existing records to determine uniqueness. Sometimes you only need to validate within given conditions. You can perform conditionals using an approach like the following. Sometimes the helpers aren't enough and you might need something more custom.
You can create your own methods that do some validations you roll yourself. Note here I'm validating this method using the :on option which lets you determine where to initialize the validation. In this case I chose :create. You can also hook into the errors collection as I have to amend what outputs on the client-side if you need to.
We don't have the :message on custom methods in this case. Read more about errors. They have been created in the exact same second. My guess is that something happened on the workers and for some reason they got invoked at the same time or the queue frozen and when it got back it ran the same job twice.
I don't understand why rails let the above to pass maybe because workers run on different threads plays a role? I added the following migration:. When you persist a user instance, Rails will validate your model by running a SELECT query to see if any user records already exist with the provided email. Most of the time it is desirable to have an index on database level to avoid these race conditions too. Any guess what could have caused the workers to run the same job more than one and exactly the same second?
Most background job libraries only guarantee that at least one job gets enqueued but not exactly one. Your jobs should always be idempotent can run several times. A good read is this guide about ActiveJob design , especially the part about idempotency. Given the nature of the validator usually are called during callbacks and there are not thread-safe meaning that they can run into race conditions, how common this can happens depends on your application, you should add always the validation on the DB as well.
Stack Overflow for Teams — Collaborate and share knowledge with a private group. Create a free Team What is Teams? Collectives on Stack Overflow. Learn more. Rails unique validation didn't worked and background jobs Ask Question.
0コメント