1

I have a query, but I want to call it now and wish it to be executed after few mins and seconds. Please note: I don't want to use SLEEP(), as it 'freezes' the entire database. I want one of the queries to be delayed while I perform the others queries in a default manner.

Small example that doesn't works:

WAITFOR DELAY '00:00:10'
update users set 'id' = 10 where `id` > 5

WAITFOR DELAY is a SQL Server command

How do I solve this problem?

John K. N.
18.9k14 gold badges56 silver badges117 bronze badges
asked Aug 27, 2018 at 22:26
5
  • 1
    This is an odd thing to ask. Why do you want a delay? What high problem are you solving? If you are having trouble accessing a table or updating it make sure its Innodb and not MyISAM as it uses table level locks to preserve integrity. Commented Aug 27, 2018 at 23:13
  • I am about to make small game. I have no troubles accessing tables. Commented Aug 27, 2018 at 23:15
  • 1
    "small game" bit high level and brief in describing the problem that you want to address at a SQL level. Commented Aug 27, 2018 at 23:18
  • lets say user clicks 'bake food'. food as 'baked' should be marked as complete in table after 1 hour. Commented Aug 27, 2018 at 23:21
  • @BeržasSuJumis you really should handle this outside sql. It will keep the connection with database open for 1 hour in given case and that's not good.. Commented Aug 28, 2018 at 13:52

5 Answers 5

2

You could create an event.

Rather than SLEEP in the same statement as an update try: 'SELECT SLEEP(360); UPDATE ....'.

answered Aug 27, 2018 at 23:12
2
  • Its a drawback, as event making requires SUPER privillegies. Anything like that?: CREATE EVENT DO_INSERT_OP ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND DO INSERT INTO mytable (name,surname) VALUES ('john','john'); Commented Aug 27, 2018 at 23:14
  • @BeržasSuJumis Event mentioning must be skipped. SELECT SLEEP(360); UPDATE .... is a solution you need (don't forget to check that your connector allows multi-queries). Commented Aug 28, 2018 at 5:09
1

Or have a table

| item | state | time |

You can insert a new state at any time. When you retrieve an item SELECT item, state FROM table WHERE item='X' AND time > NOW() ORDER BY time DESC LIMIT 1

answered Aug 28, 2018 at 5:14
0

So you are creating a job, create separate cron process which runs on your server every x minutes and checks the stuff needs to be done. On your baking field add timestamp when it was submitted.

1) on sql site every enter has current timestamp when even was submitted and how long it should take 2) Create cron job runs every minute which checks if the goods are done runs your second query on it

answered Aug 28, 2018 at 0:19
0

Another way to do the same as in danblack's solution (quote):

Rather than SLEEP in the same statement as an update try:

SELECT SLEEP(360); UPDATE ....

UPDATE (SELECT SLEEP(360)) dummy, -- may use JOIN instead of comma
 tableset_for_update
SET fieldset_to_update = new_values
WHERE conditions

Can be applied to multi-table update (always) or single-table update (if it do not contain ORDER BY clause).

answered Aug 28, 2018 at 5:06
0

You may also want to look into using named locks. Here are the functions:

  • GET_LOCK() : Tries to obtain a lock with a name given by the string str, using a timeout of timeout seconds. A negative timeout value means infinite timeout. The lock is exclusive. While held by one session, other sessions cannot obtain a lock of the same name. Returns 1 if the lock was obtained successfully, 0 if the attempt timed out (for example, because another client has previously locked the name), or NULL if an error occurred (such as running out of memory or the thread was killed with mysqladmin kill).
  • RELEASE_LOCK() : Releases the lock named by the string str that was obtained with GET_LOCK(). Returns 1 if the lock was released, 0 if the lock was not established by this thread (in which case the lock is not released), and NULL if the named lock did not exist. The lock does not exist if it was never obtained by a call to GET_LOCK() or if it has previously been released.
  • RELEASE_ALL_LOCKS() : Releases all named locks held by the current session and returns the number of locks released (0 if there were none).
  • Please read carefully the MySQL Documentation on these.

In your case, you may want to do something like this:

DO GET_LOCK('update_roadblock',10);
update users set 'id' = 10 where `id` > 5;
DO RELEASE_LOCK('update_roadblock');

This will attempt to create a named locked called update_roadblock:

  • If the lock is acquired in less than 10 seconds, it will execute the update.
  • If the lock is not acquired in 10 seconds, lock attempt times out and executes the update.

In both cases, the delay is up to 10 seconds.

Since you are coding a game, then you may want to run DO GET_LOCK('update_roadblock',-1); to own the lock somewhere else in the code. When done with the part of the game needing the lock first, you simply call DO RELEASE_LOCK('update_roadblock'); or DO RELEASE_ALL_LOCKS();. Then, the part of the code that is waiting to run update users set 'id' = 10 where id > 5 will proceed if the delay is less than 10 seconds or proceed after 10 seconds.

GIVE IT A TRY !!!

answered Aug 28, 2018 at 13:23

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.