1

I am using a script that sync data betweens two databases (locally to an hosted domain). I made the sync occurs when someone log out from the CMS. Unfortunatly, I have seen cases when two logout happen close enough that the sync script is executed twice. It's not the part of the system I'm trying to change but I was expecting an easy way to makes that script (sync.php) not executing if it's already running.

I have came up with that test scripts:

$db = new DB_Mysql();

if ( $db->transactionBegun() == "0" )
{
    $_Continue = true;

    $_Continue = $_Continue && $db->squery( "START TRANSACTION" );

    $_Continue = $_Continue && $db->squery( "SET @TransactionBegun = true" );

    sleep( 10 );

    $_Continue = $_Continue && $db->squery( "INSERT INTO tbConfiguration VALUES( NOW(), NOW() )" );

    $_Continue = $_Continue && $db->squery( "SET @TransactionBegun = false" );

    if ( $_Continue )
    {
        $db->query( "COMMIT" );
    } else {
        $db->query( "ROLLBACK" );
    }
}

The transactionBegun method consist of:

    function transactionBegun()
    {
        $_ResultSet = $this->query("SELECT @TransactionBegun AS TransactionBegun")->fetch_all(true);

        return $_ResultSet[ 'TransactionBegun' ];
    }

For some strange alien reason, I can run the script twice (in the same time) and both entry will be made.

Any ideas??

Edit: I forgot to mention that I am using a mysql_pconnect() and that the server is hosted on a Windows machine. The whole system is a cash register machine using a tablet PC. The only client accessing the server is "localhost".

2
  • @Variables only exist on your connection, they're not global. You need to use locks to prevent multiple clients from interacting with the tables/rows at the same time. Commented Aug 11, 2011 at 21:15
  • I forgot to specify that my library use a mysql_pconnect(). Commented Aug 11, 2011 at 21:21

3 Answers 3

1

The variables are per-connection, not per-user. With two independent scripts, you'll have two seperate independent connections, each with its own variable space.

If you need to truly handle locking out parallel usage, you'll need to use a server-side lock acquired via GET_LOCK() or use a transaction mode that does exclusive locking on the resource.

Sign up to request clarification or add additional context in comments.

2 Comments

This is a better solution than file locks if you want the lock to work across multiple terminals.
I will gives it a try tomorrow and gives you feedback!
1

Use file-based locks.

When the script begins, have it check for a file like "sync_db.lock". If it exists, another instance of the script is running. At this point, you can choose to sleep for a few seconds and begin again, or simply give up.

If it doesn't exist, create the file and complete the DB transaction. When the transaction is completed, simply delete the file.

To avoid issues with failed threads, write the current timestamp to the file. When the script checks for the file, read its contents and see if a given time period has passed. Don't forget to overwrite the timestamp if your script continues with the transaction.

Comments

0

A little psudo code: check to see if a file (/var/tmp/.trans.lck) is there if it is exit create lock file if not when finish remove lock file

1 Comment

There's no reason to implement your own locking scheme when MySQL provides access to global locks, table locks, row-level locks, queries that implement automatic locks, transaction lock modes, etc.

Your Answer

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.