The problem is to make a selection and then insert, then there is usually a read lock for selection and then a write lock for insert. Without a transaction, many updates often allow multiple inserts to appear, as you can see. In a transaction, the first read lock stops other processes that receive a write lock, and if more than one process gets a read lock, then no one can get a write lock, and therefore you get a deadlock.
In this case, I would change the insertion code so that the indices allow only one insertion to work, i.e. you have a unique key, and only one process will not be able to insert data, so there will be no duplicates. The update process is then performed in a transaction either
1) insert the tab first and handle the exception or error if it tries to insert a duplicate
or 2) do HOLD LOCK (Sybase and SQL Server) at the first choice - thus, the first one for blocking gets full permission to insert if necessary
or 3) Perhaps use the merge command if RDBMS allows it. This checks and inserts everything into one command, but will always modify the database.
EDIT: I think there is no real alternative to 1, if you need to make sure that it included one and only one record, since the test should be in a transaction.
cost can be reduced by checking forst in one transaction and then inserting and checking another transaction a second time. Thus, in most cases you have a choice, and in other cases you get a complete slow insertion and validation, but this should happen less often.
Mark
source share