A
A
Anton Morozov2020-06-06 22:20:08
PHP
Anton Morozov, 2020-06-06 22:20:08

How to prevent double processing of one row from the base?

Ladies and gentlemen, greetings.

There is a table in the database (conditionally):
Name Processing time
Line 1 10:00
Line 2 10:01
Line 3 10:02
........................ ....
Line N 23:59

There are conditionally 10 scripts that are simultaneously launched by the cron.
10 scripts are 10 identical PHP files that differ only in authorization data.

All 10 scripts refer to this table during their work.
Everyone takes the most "stale line". In our case, the one that was processed at 10:00.
After that, it sets the current date / time to the "Processing time" column, processes it.
After processing, it returns to the same table and again on a new one.

The main task is to provide a minimum interval between accesses to each line.

The option when each script has its own part of the table is not suitable - if the account through which the script is authorized is conditionally "banned" - the part of the table will not be processed.

We will consider scripts as demons that work constantly.
The processing time for one line is always different.

The situation when 2 scripts access the same line is more than possible.
And there will be some time between the two SELECT and UPDATE queries anyway.

How to prevent a situation where several scripts simultaneously accessed the same table row and took it to work?

As a result of this behavior, information will be duplicated in the place where the script is executed, which cannot be allowed in any way.

PS I know I don't know anything. I know it's wrong to do so. I know that my knowledge of architecture hangs around zero.
But I want to solve this problem in the most efficient way.
I read books and learn materiel.
If you want to notify me that it's better for me to quit programming and not write anything here, don't waste your time.

Answer the question

In order to leave comments, you need to log in

5 answer(s)
M
Maksim Fedorov, 2020-06-06
@fanofmarta

Skip locked
https://mysqlserverteam.com/mysql-8-0-1-using-skip...

V
vism, 2020-06-06
@vism

you need to write a unique ID and select a line by it.
Those.
1. generate a hash in the script
2. make an update with this hash
3. take a line from this hash and work it out.

T
toxa82, 2020-06-06
@toxa82

Use LOCK TABLES tbl_name WRITE, then even reading is blocked for other threads.

F
FanatPHP, 2020-06-07
@FanatPHP

https://qna.habr.com/answer?answer_id=1507863#answ...

M
MaLuTkA_UA, 2020-06-06
@MaLuTkA_UA

Presumably your table contains tasks in the following format:
id | execute_in | executed_at
1 | 10:00 | null
2 ​​| 10:01 | null
So, to select in the postgresql language, you can execute the following query
UPDATE jobs SET executed_at = now() WHERE id = (SELECT id FROM jobs WHERE execute_in <= now() AND executed_at is null LIMIT 1) AND executed_at is null RETURNING id
Tem thus we update only one record and after updating it we get its id, or the entire record

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question