PhpRiot
Follow phpriot on Twitter
Sponsored Link
Download Article
Download this article in PDF format with all listings and files.

Price: $5.00 AUD
(Approx. $5.00 USD)

More information
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store
Free iPad/iPhone App
Available on the App Store

  • PHP manual
  • Zend Framework manual
  • Smarty manual
  • PHP articles
  • PHP training

Understanding Transactions And Locking In PostgreSQL

Automation With PLPGSQL

Now we need to actually do something useful with this information.

We will create a plpgsql function block that will determine if the user has a 5 dollar positive balance, insert into some other table (to simulate the purchase of some item), and then post a 5 dollar debit to the users account.

For those not familiar with plpgsql it’s extremely easy to use. Just be sure to use the createlang binary in the PostgreSQL distribution to add plpgsql support to your database. (/usr/local/pgsql/bin/createlang plpgsql yourdbname) as the postgres user.

Listing 3 listing-3.sql
CREATE OR REPLACE FUNCTION buysomething(varchar(255),TEXT) RETURNS integer AS $$
    DECLARE
        account_balance NUMERIC(22,9);
    BEGIN
        SELECT (SUM(COALESCE(credit,0)) - SUM(COALESCE(debit,0)) INTO account_balance
            FROM accounting
            WHERE account_id = $1;
 
        IF account_balance >= 5 THEN
            INSERT INTO purchases (SomeTextCol) VALUES ($2);
            INSERT INTO accounting (account_id, debit) VALUES ($1, 5);
        ELSE
            RAISE EXCEPTIONThe account % does not have enough free balance’, $1;
        END IF;
    END;
$$ Language plpgsql;

Note: there are better ways to write this function, but this method demonstrates the most functionality.

So this function looks like it would do the job, but there’s a trick. What happens if this function is called twice at the same identical time?

Well what happens is between the balance selection and the insert into accounting, another debit could have been committed to the accounting table. There is no guarantee that after the select is run the balance will not change until the end of the function.

In This Article