From e.ghanem@acteos.com Mon Jun 14 12:50:04 2010 Received: from maia.hub.org (maia-3.hub.org [200.46.204.243]) by mail.postgresql.org (Postfix) with ESMTP id 6DEF16302CB for ; Mon, 14 Jun 2010 09:50:04 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.243]) (amavisd-maia, port 10024) with ESMTP id 70156-10 for ; Mon, 14 Jun 2010 12:49:55 +0000 (UTC) X-Greylist: delayed 00:58:49.900118 by SQLgrey-1.7.6 Received: from mailrelay100-out.ornis.com (mailrelay100-out.ornis.com [81.93.1.91]) by mail.postgresql.org (Postfix) with ESMTP id D722D62F1B2 for ; Mon, 14 Jun 2010 09:49:56 -0300 (ADT) Received: from fsecure100.ornis.com ([192.168.162.100]) by mailrelay100-out.ornis.com (8.13.1/8.13.1) with ESMTP id o5EBp3U3010591 for ; Mon, 14 Jun 2010 13:51:03 +0200 Received: from unknown (HELO relay-ext.ornis.com) ([192.168.160.6]) by mailgate402.ornis.com with ESMTP; 14 Jun 2010 13:51:03 +0200 Received: from [192.168.0.71] ([80.79.155.178]) by relay-ext.ornis.com (8.12.9/8.12.3) with ESMTP id o5EBp0lu000804 for ; Mon, 14 Jun 2010 13:51:01 +0200 Message-ID: <4C161793.2090105@acteos.com> Date: Mon, 14 Jun 2010 14:50:43 +0300 From: Elias Ghanem User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1.9) Gecko/20100317 Thunderbird/3.0.4 MIME-Version: 1.0 To: pgsql-performance@postgresql.org Subject: Dead lock Content-Type: multipart/alternative; boundary="------------060101050504020706040401" X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-0.499 tagged_above=-10 required=5 tests=BAYES_05=-0.5, HTML_MESSAGE=0.001 X-Spam-Level: X-Archive-Number: 201006/242 X-Sequence-Number: 39098 This is a multi-part message in MIME format. --------------060101050504020706040401 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi all, I have 2 data bases trying to perform an update query at the same time on a same table in a third data base using db link. I'm getting a dead lock exception: ERROR: deadlock detected DETAIL: Process 27305 waits for ShareLock on transaction 55575; blocked by process 27304. Process 27304 waits for ShareLock on transaction 55576; blocked by process 27305. HINT: See server log for query details. Actually the folowing function is installed on 2 dbs DB1 and DB2. This function issues an update query on DB3. When this function is running simultaneously on DB1 and DB2, it produces a dead lock making one of the functions (in DB1 or DB2) stop with the above exception: Is it normal? should'nt postgres be able to handle such situations, for ex: let one transaction wait untill the other commits or rollback then continue with the first transaction? Is there a parameter that should be set in postgresql.conf to allow handling of concurrent transaction...? CREATE OR REPLACE FUNCTION TEST_DB_LINK(VARCHAR) RETURNS VOID AS' DECLARE C INTEGER; P ALIAS FOR $1; DUMMY VARCHAR; BEGIN C:= 0; LOOP EXIT WHEN C > 15; C:= C+1; SELECT INTO DUMMY DBLINK_EXEC(''CONNECTION_STRING TO DB3', ''UPDATE IN_FICHE_PRODUIT SET VALIDE = 1''); RAISE NOTICE ''%, %'', C,P; END LOOP; END;' LANGUAGE 'plpgsql'; Thanks for your time. --------------060101050504020706040401 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Hi all,
I have 2 data bases trying to perform an update query at the same time on a same table in a third data base using db link.
I'm getting a dead lock exception:
ERROR:  deadlock detected
DETAIL:  Process 27305 waits for ShareLock on transaction 55575; blocked by process 27304.
Process 27304 waits for ShareLock on transaction 55576; blocked by process 27305.
HINT:  See server log for query details.
Actually the folowing function is installed on 2 dbs DB1 and DB2. This function issues an update query on DB3.
When this function is running simultaneously on DB1 and DB2, it produces a dead lock making one of the functions (in DB1 or DB2) stop with the above exception:
Is it normal? should'nt postgres be able to handle such situations, for ex:  let one transaction wait untill the other commits or rollback then continue with the first transaction?
Is there a parameter that should be set in postgresql.conf to allow handling of concurrent transaction...?

CREATE OR REPLACE FUNCTION TEST_DB_LINK(VARCHAR)
RETURNS VOID AS'
DECLARE
C INTEGER;
P ALIAS FOR $1;
DUMMY  VARCHAR;
BEGIN   
    C:= 0;
    LOOP
        EXIT WHEN C > 15;
        C:= C+1;
        SELECT INTO DUMMY DBLINK_EXEC(''CONNECTION_STRING TO DB3', ''UPDATE IN_FICHE_PRODUIT SET VALIDE = 1'');
    RAISE NOTICE ''%, %'', C,P;
    END LOOP;
END;'
LANGUAGE 'plpgsql';

Thanks for your time.
--------------060101050504020706040401-- From tom@audioboundary.com Mon Jun 14 12:54:46 2010 Received: from maia.hub.org (maia-3.hub.org [200.46.204.243]) by mail.postgresql.org (Postfix) with ESMTP id 78187632992 for ; Mon, 14 Jun 2010 09:54:46 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.243]) (amavisd-maia, port 10024) with ESMTP id 72211-06 for ; Mon, 14 Jun 2010 12:54:37 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from beaker.bytemark.co.uk (beaker.bytemark.co.uk [80.68.81.2]) by mail.postgresql.org (Postfix) with ESMTP id 7B90A632403 for ; Mon, 14 Jun 2010 09:54:39 -0300 (ADT) Received: from tetrarch.vm.bytemark.co.uk ([89.16.174.118] helo=mail.audioboundary.com) by beaker.bytemark.co.uk with esmtp (Exim 4.69) (envelope-from ) id 1OO9BW-0003aL-25 for pgsql-performance@postgresql.org; Mon, 14 Jun 2010 13:54:38 +0100 Received: from [86.6.239.186] (cpc5-lewi13-2-0-cust185.know.cable.virginmedia.com [86.6.239.186]) by mail.audioboundary.com (Postfix) with ESMTPSA id C807FE048F for ; Mon, 14 Jun 2010 13:54:34 +0100 (BST) Message-ID: <4C162680.8090502@audioboundary.com> Date: Mon, 14 Jun 2010 13:54:24 +0100 From: Tom Molesworth User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9pre) Gecko/20100217 Shredder/3.0.3pre MIME-Version: 1.0 To: pgsql-performance@postgresql.org Subject: Re: Dead lock References: <4C161793.2090105@acteos.com> In-Reply-To: <4C161793.2090105@acteos.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0.8 tagged_above=-10 required=5 tests=BAYES_50=0.8 X-Spam-Level: X-Archive-Number: 201006/243 X-Sequence-Number: 39099 On 14/06/10 12:50, Elias Ghanem wrote: > SELECT INTO DUMMY DBLINK_EXEC(''CONNECTION_STRING TO DB3', > ''UPDATE IN_FICHE_PRODUIT SET VALIDE = 1''); If there's more than one value in that table, an explicit ORDER BY might help (otherwise you could get the situation where query A will update in the order 1,2,3 and query B will do 3,2,1 so neither will be able to get the requested locks until the other query has finished). Tom From andy@squeakycode.net Mon Jun 14 13:59:50 2010 Received: from maia.hub.org (maia-2.hub.org [200.46.204.251]) by mail.postgresql.org (Postfix) with ESMTP id 9D6F1632AC5 for ; Mon, 14 Jun 2010 10:59:50 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.251]) (amavisd-maia, port 10024) with ESMTP id 80927-09 for ; Mon, 14 Jun 2010 13:59:42 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from marajade.localdomain (vcs5.camavision.com [63.228.164.252]) by mail.postgresql.org (Postfix) with ESMTP id 8435E632521 for ; Mon, 14 Jun 2010 10:59:43 -0300 (ADT) Received: from [192.168.1.103] (173-20-246-8.client.mchsi.com [173.20.246.8]) (Authenticated sender: andy) by marajade.localdomain (Postfix) with ESMTPA id 9522359A49; Mon, 14 Jun 2010 08:59:41 -0500 (CDT) Message-ID: <4C1635CC.8060801@squeakycode.net> Date: Mon, 14 Jun 2010 08:59:40 -0500 From: Andy Colson User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100317 Lightning/1.0b1 Thunderbird/3.0.4 MIME-Version: 1.0 To: Elias Ghanem , pgsql-performance@postgresql.org Subject: Re: Dead lock References: <4C161793.2090105@acteos.com> In-Reply-To: <4C161793.2090105@acteos.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-0.001 tagged_above=-10 required=5 tests=BAYES_40=-0.001 X-Spam-Level: X-Archive-Number: 201006/246 X-Sequence-Number: 39102 On 06/14/2010 06:50 AM, Elias Ghanem wrote: > Hi all, > I have 2 data bases trying to perform an update query at the same time > on a same table in a third data base using db link. > I'm getting a dead lock exception: > ERROR: deadlock detected > DETAIL: Process 27305 waits for ShareLock on transaction 55575; blocked > by process 27304. > Process 27304 waits for ShareLock on transaction 55576; blocked by > process 27305. > HINT: See server log for query details. > Actually the folowing function is installed on 2 dbs DB1 and DB2. This > function issues an update query on DB3. > When this function is running simultaneously on DB1 and DB2, it produces > a dead lock making one of the functions (in DB1 or DB2) stop with the > above exception: > Is it normal? should'nt postgres be able to handle such situations, for > ex: let one transaction wait untill the other commits or rollback then > continue with the first transaction? > Is there a parameter that should be set in postgresql.conf to allow > handling of concurrent transaction...? > > CREATE OR REPLACE FUNCTION TEST_DB_LINK(VARCHAR) > RETURNS VOID AS' > DECLARE > C INTEGER; > P ALIAS FOR $1; > DUMMY VARCHAR; > BEGIN > C:= 0; > LOOP > EXIT WHEN C > 15; > C:= C+1; > SELECT INTO DUMMY DBLINK_EXEC(''CONNECTION_STRING TO DB3', ''UPDATE > IN_FICHE_PRODUIT SET VALIDE = 1''); > RAISE NOTICE ''%, %'', C,P; > END LOOP; > END;' > LANGUAGE 'plpgsql'; > > Thanks for your time. I think PG is doing what you want.. if you think about it. You start two transactions at the same time. A transaction is defined as "do this set of operations, all of which must succeed or fail atomicly". One transaction cannot update the exact same row as another transaction because that would break the second transactions "must succeed" rule. -Andy From e.ghanem@acteos.com Mon Jun 14 15:37:25 2010 Received: from maia.hub.org (maia-5.hub.org [200.46.204.29]) by mail.postgresql.org (Postfix) with ESMTP id 1BB0A632281 for ; Mon, 14 Jun 2010 12:37:25 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.29]) (amavisd-maia, port 10024) with ESMTP id 51433-01 for ; Mon, 14 Jun 2010 15:37:17 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mailrelay101-out.ornis.com (mailrelay101-out.ornis.com [81.93.1.89]) by mail.postgresql.org (Postfix) with ESMTP id D110D6321B1 for ; Mon, 14 Jun 2010 12:37:16 -0300 (ADT) Received: from fsecure101.ornis.com ([192.168.162.101]) by mailrelay101-out.ornis.com (8.13.1/8.13.1) with ESMTP id o5EFbDgN028249 for ; Mon, 14 Jun 2010 17:37:13 +0200 Received: from unknown (HELO relay-ext.ornis.com) ([192.168.160.6]) by mailgate401.ornis.com with ESMTP; 14 Jun 2010 17:37:13 +0200 Received: from [192.168.0.71] ([80.79.155.178]) by relay-ext.ornis.com (8.12.9/8.12.3) with ESMTP id o5EFbAlu003398 for ; Mon, 14 Jun 2010 17:37:11 +0200 Message-ID: <4C164C9A.5030607@acteos.com> Date: Mon, 14 Jun 2010 18:36:58 +0300 From: Elias Ghanem User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1.9) Gecko/20100317 Thunderbird/3.0.4 MIME-Version: 1.0 To: pgsql-performance@postgresql.org Subject: Fwd: Dead lock Content-Type: multipart/alternative; boundary="------------030400080803020608000606" X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0 tagged_above=-10 required=5 tests=BAYES_40=-0.001, HTML_MESSAGE=0.001 X-Spam-Level: X-Archive-Number: 201006/248 X-Sequence-Number: 39104 This is a multi-part message in MIME format. --------------030400080803020608000606 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi, Actually i guess the problem is related to the way PG uses to aquire lock on the rows that will be updated. Suppose the update query will affect 5 rows: A, B, C, D and E. Apparently the folowing senario is happening: 1- Transaction1 locks row A 2- Trnasaction2 locks row B 3- Transaction1 updates row A 4- Tranasaction2 updates row B 5- Transaction1 *tries *to acquire lock on row B(and fail because row B is still locked by transaction2) 6- Transaction2 *tries *to acquire lock on row A(and fail because row A is still locked by transaction1) Hence the dead lock. Is this a plausible explanation of what is going on? If yes, what can be done to avoid the dead lock? Thanks again. -------- Original Message -------- Subject: Dead lock Date: Mon, 14 Jun 2010 14:50:43 +0300 From: Elias Ghanem To: pgsql-performance@postgresql.org Hi all, I have 2 data bases trying to perform an update query at the same time on a same table in a third data base using db link. I'm getting a dead lock exception: ERROR: deadlock detected DETAIL: Process 27305 waits for ShareLock on transaction 55575; blocked by process 27304. Process 27304 waits for ShareLock on transaction 55576; blocked by process 27305. HINT: See server log for query details. Actually the folowing function is installed on 2 dbs DB1 and DB2. This function issues an update query on DB3. When this function is running simultaneously on DB1 and DB2, it produces a dead lock making one of the functions (in DB1 or DB2) stop with the above exception: Is it normal? should'nt postgres be able to handle such situations, for ex: let one transaction wait untill the other commits or rollback then continue with the first transaction? Is there a parameter that should be set in postgresql.conf to allow handling of concurrent transaction...? CREATE OR REPLACE FUNCTION TEST_DB_LINK(VARCHAR) RETURNS VOID AS' DECLARE C INTEGER; P ALIAS FOR $1; DUMMY VARCHAR; BEGIN C:= 0; LOOP EXIT WHEN C > 15; C:= C+1; SELECT INTO DUMMY DBLINK_EXEC(''CONNECTION_STRING TO DB3', ''UPDATE IN_FICHE_PRODUIT SET VALIDE = 1''); RAISE NOTICE ''%, %'', C,P; END LOOP; END;' LANGUAGE 'plpgsql'; Thanks for your time. --------------030400080803020608000606 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Hi,
Actually i guess the problem is related to the way PG uses to aquire lock on the rows that will be updated.
Suppose the update query will affect 5 rows: A, B, C, D and E.
Apparently the folowing senario is happening:
    1- Transaction1 locks row A
    2- Trnasaction2 locks row B
    3- Transaction1 updates row A
    4- Tranasaction2 updates row B
    5- Transaction1 tries to acquire lock on row B(and fail because row B is still locked by transaction2)
    6- Transaction2 tries to acquire lock on row A(and fail because row A is still locked by transaction1)
Hence the dead lock.
Is this a plausible explanation of what is going on?
If yes, what can be done to avoid the dead lock?
Thanks again.


-------- Original Message --------
Subject: Dead lock
Date: Mon, 14 Jun 2010 14:50:43 +0300
From: Elias Ghanem <e.ghanem@acteos.com>
To: pgsql-performance@postgresql.org


Hi all,
I have 2 data bases trying to perform an update query at the same time on a same table in a third data base using db link.
I'm getting a dead lock exception:
ERROR:  deadlock detected
DETAIL:  Process 27305 waits for ShareLock on transaction 55575; blocked by process 27304.
Process 27304 waits for ShareLock on transaction 55576; blocked by process 27305.
HINT:  See server log for query details.
Actually the folowing function is installed on 2 dbs DB1 and DB2. This function issues an update query on DB3.
When this function is running simultaneously on DB1 and DB2, it produces a dead lock making one of the functions (in DB1 or DB2) stop with the above exception:
Is it normal? should'nt postgres be able to handle such situations, for ex:  let one transaction wait untill the other commits or rollback then continue with the first transaction?
Is there a parameter that should be set in postgresql.conf to allow handling of concurrent transaction...?

CREATE OR REPLACE FUNCTION TEST_DB_LINK(VARCHAR)
RETURNS VOID AS'
DECLARE
C INTEGER;
P ALIAS FOR $1;
DUMMY  VARCHAR;
BEGIN   
    C:= 0;
    LOOP
        EXIT WHEN C > 15;
        C:= C+1;
        SELECT INTO DUMMY DBLINK_EXEC(''CONNECTION_STRING TO DB3', ''UPDATE IN_FICHE_PRODUIT SET VALIDE = 1'');
    RAISE NOTICE ''%, %'', C,P;
    END LOOP;
END;'
LANGUAGE 'plpgsql';

Thanks for your time.

--------------030400080803020608000606-- From dcrooke@gmail.com Mon Jun 14 15:58:31 2010 Received: from maia.hub.org (maia-3.hub.org [200.46.204.243]) by mail.postgresql.org (Postfix) with ESMTP id F393563266A for ; Mon, 14 Jun 2010 12:58:31 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.243]) (amavisd-maia, port 10024) with ESMTP id 49204-07 for ; Mon, 14 Jun 2010 15:58:24 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-bw0-f46.google.com (mail-bw0-f46.google.com [209.85.214.46]) by mail.postgresql.org (Postfix) with ESMTP id E52AF632667 for ; Mon, 14 Jun 2010 12:58:23 -0300 (ADT) Received: by bwz7 with SMTP id 7so2176350bwz.19 for ; Mon, 14 Jun 2010 08:58:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:in-reply-to :references:date:message-id:subject:from:to:cc:content-type; bh=4rqo3CDRMOze/mkI6dfgMGUzfc88VHBzJF17xv5c+e4=; b=R5oFIPwF+++EMfP1tNID4hAKDbiysNFOvHiQXtgQ3qkphWqmz5S8U6lW/7utaiZxqo UtLeyfxvrvXvUocHPD5/SUM2YoSXGQPnyseCLR0nJRz9bBHWOBRtEj/+heN70pmmgGQx 1LJSC3IR6SYTkSF9EGPome9+NgJnt8tjKOi9A= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; b=GLHZ3D32lqidaxrdzRY4sVeqBfgECbyGf/nZjOhjxSvCAyuLRInYjhziglMZ3emIiL g2CeyvkW3tY/pJZqtBIC+sGKhELTyg45yElwC3yRouJUdDCmmlVW7WoOksdvJyn9/uUR /As90iMPt1Vtcac21XX394ok0bw9M076wOgkc= MIME-Version: 1.0 Received: by 10.204.47.25 with SMTP id l25mr4441388bkf.46.1276531100686; Mon, 14 Jun 2010 08:58:20 -0700 (PDT) Received: by 10.204.70.74 with HTTP; Mon, 14 Jun 2010 08:58:20 -0700 (PDT) In-Reply-To: <4C164C9A.5030607@acteos.com> References: <4C164C9A.5030607@acteos.com> Date: Mon, 14 Jun 2010 10:58:20 -0500 Message-ID: Subject: Re: Fwd: Dead lock From: Dave Crooke To: Elias Ghanem Cc: pgsql-performance@postgresql.org Content-Type: multipart/alternative; boundary=0016e6d64cfccd19040488ff8e77 X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0.801 tagged_above=-10 required=5 tests=BAYES_50=0.8, HTML_MESSAGE=0.001 X-Spam-Level: X-Archive-Number: 201006/249 X-Sequence-Number: 39105 --0016e6d64cfccd19040488ff8e77 Content-Type: text/plain; charset=UTF-8 It's a standard (indeed, required) best practice of concurrent database programming across any brand of database to ensure that multi-row transactions always acquire the locks they use in a predictable order based on row identities, e.g. for the classic banking debit-credit pair, doing something like this (Java / JDBC, simplified for brevity and clarity): PreparedStatement debit = conn.prepareStatement("update account set balance = balance - ? where acc_no = ? and balance > ?"); debit.setLong(1, amount); debit.setLong(2, debit_acct); debit.setLong(3, amount); PreparedStatement credit = conn.prepareStatement("update account set balance = balance + ? where acc_no = ?"); credit.setLong(1, amount); credit.setLong(2, credit_acct); try { // always acquire row locks in increasing account number order conn.beginTransaction(); if (credit_acct < debit_acct) { credit.executeUpdate(); if (debit.executeUpdate() < 1) throw new SQLException("Insufficient balance"); } else { if (debit.executeUpdate() < 1) throw new SQLException("Insufficient balance"); credit.executeUpdate(); } } catch (SQLException e) { System.err.println("Oops. transaction failed: ", e.getMessage()); conn.rollback(); } conn.commit(); If you're doing straight SQL bulk updates, then as someone suggested, you could use an ORDER BY on a subquery, but I don't know if that is a guarantee, if you're not actually displaying the results then the DB may be technically allowed to optimize it out from underneath you. The only way to be sure is a cursor / procedure. In short, this boils down to learning more about database programming. PG is performing as it should. Cheers Dave On Mon, Jun 14, 2010 at 10:36 AM, Elias Ghanem wrote: > Hi, > Actually i guess the problem is related to the way PG uses to aquire lock > on the rows that will be updated. > Suppose the update query will affect 5 rows: A, B, C, D and E. > Apparently the folowing senario is happening: > 1- Transaction1 locks row A > 2- Trnasaction2 locks row B > 3- Transaction1 updates row A > 4- Tranasaction2 updates row B > 5- Transaction1 *tries *to acquire lock on row B(and fail because row > B is still locked by transaction2) > 6- Transaction2 *tries *to acquire lock on row A(and fail because row > A is still locked by transaction1) > Hence the dead lock. > Is this a plausible explanation of what is going on? > If yes, what can be done to avoid the dead lock? > Thanks again. > > > > -------- Original Message -------- Subject: Dead lock Date: Mon, 14 Jun > 2010 14:50:43 +0300 From: Elias Ghanem To: > pgsql-performance@postgresql.org > > Hi all, > I have 2 data bases trying to perform an update query at the same time on a > same table in a third data base using db link. > I'm getting a dead lock exception: > ERROR: deadlock detected > DETAIL: Process 27305 waits for ShareLock on transaction 55575; blocked by > process 27304. > Process 27304 waits for ShareLock on transaction 55576; blocked by process > 27305. > HINT: See server log for query details. > Actually the folowing function is installed on 2 dbs DB1 and DB2. This > function issues an update query on DB3. > When this function is running simultaneously on DB1 and DB2, it produces a > dead lock making one of the functions (in DB1 or DB2) stop with the above > exception: > Is it normal? should'nt postgres be able to handle such situations, for > ex: let one transaction wait untill the other commits or rollback then > continue with the first transaction? > Is there a parameter that should be set in postgresql.conf to allow > handling of concurrent transaction...? > > CREATE OR REPLACE FUNCTION TEST_DB_LINK(VARCHAR) > RETURNS VOID AS' > DECLARE > C INTEGER; > P ALIAS FOR $1; > DUMMY VARCHAR; > BEGIN > C:= 0; > LOOP > EXIT WHEN C > 15; > C:= C+1; > SELECT INTO DUMMY DBLINK_EXEC(''CONNECTION_STRING TO DB3', ''UPDATE > IN_FICHE_PRODUIT SET VALIDE = 1''); > RAISE NOTICE ''%, %'', C,P; > END LOOP; > END;' > LANGUAGE 'plpgsql'; > > Thanks for your time. > > --0016e6d64cfccd19040488ff8e77 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable It's a standard (indeed, required) best practice of concurrent database= programming across any brand of database to ensure that multi-row transact= ions always acquire the locks they use in a predictable order based on row = identities, e.g. for the classic banking debit-credit pair, doing something= like this (Java / JDBC, simplified for brevity and clarity):

PreparedStatement d= ebit =3D conn.prepareStatement("update account set=20 balance =3D balance - ? where acc_no =3D ? and balance > ?");
debit.setLong(1, amount);
debit.setLong(2, debit_= acct);
debit.setLong(3, amount);
PreparedStatement credit =3D conn.prepareStateme= nt("update account set=20 balance =3D balance + ? where acc_no =3D ?");
credit.setLong(1, amoun= t);
credit.setLong(2, credit_acct);=

try {
=C2=A0=C2= =A0 // always acquire row locks in increasing account number order =C2=A0=C2=A0 conn.begin= Transaction();
=C2=A0=C2=A0 if (credit_acc= t < debit_acct) {

=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 credit.executeUpdate();
=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 if=20 (debit.executeUpdate() < 1) throw new SQLException("Insufficient=20 balance");
=C2=A0=C2=A0 }
=C2=A0=C2=A0 else {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if=20 (debit.executeUpdate() < 1) throw new SQLException("Insufficient=20 balance");
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 credit.executeUpdate();<= /span>
=C2=A0=C2=A0 }}
catch (SQLExcep= tion e) {
=C2=A0=C2=A0 System.err= .println("Oops. transaction failed: ", e.getMessage());=C2=A0=C2=A0 conn.rollback();
}
conn.commit();

If you're doing straight SQL bulk updates, then as someone suggeste= d, you could use an ORDER BY on a subquery, but I don't know if that is= a guarantee, if you're not actually displaying the results then the DB= may be technically allowed to optimize it out from underneath you. The onl= y way to be sure is a cursor / procedure.

In short, this boils down to learning more about database programming. = PG is performing as it should.

Cheers
Dave

On Mon, Jun 14, 2010 at 10:36 AM, Elias Ghanem <e.ghanem@acteos.com> wrote:
=20
Hi,
Actually i guess the problem is related to the way PG uses to aquire lock on the rows that will be updated.
Suppose the update query will affect 5 rows: A, B, C, D and E.
Apparently the folowing senario is happening:
=C2=A0=C2=A0=C2=A0 1- Transaction1 locks row A
=C2=A0=C2=A0=C2=A0 2- Trnasaction2 locks row B
=C2=A0=C2=A0=C2=A0 3- Transaction1 updates row A
=C2=A0=C2=A0=C2=A0 4- Tranasaction2 updates row B
=C2=A0=C2=A0=C2=A0 5- Transaction1 tries to acquire lock on row B(an= d fail because row B is still locked by transaction2)
=C2=A0=C2=A0=C2=A0 6- Transaction2 tries to acquire lock on row A(an= d fail because row A is still locked by transaction1)
Hence the dead lock.
Is this a plausible explanation of what is going on?
If yes, what can be done to avoid the dead lock?
Thanks again.



-------- Original Message --------
Subject: Dead lock
Date: Mon, 14 Jun 2010 14:50:43 +0300
From: Elias Ghanem <e.ghanem@acteos.com>
To: pgsql-performance@postgresql.org


Hi all,
I have 2 data bases trying to perform an update query at the same time on a same table in a third data base using db link.
I'm getting a dead lock exception:
ERROR:=C2=A0 deadlock detected
DETAIL:=C2=A0 Process 27305 waits for ShareLock on transaction 55575; blocked by process 27304.
Process 27304 waits for ShareLock on transaction 55576; blocked by process 27305.
HINT:=C2=A0 See server log for query details.
Actually the folowing function is installed on 2 dbs DB1 and DB2. This function issues an update query on DB3.
When this function is running simultaneously on DB1 and DB2, it produces a dead lock making one of the functions (in DB1 or DB2) stop with the above exception:
Is it normal? should'nt postgres be able to handle such situations, for ex:=C2=A0 let one transaction wait untill the other commits or rollback the= n continue with the first transaction?
Is there a parameter that should be set in postgresql.conf to allow handling of concurrent transaction...?

CREATE OR REPLACE FUNCTION TEST_DB_LINK(VARCHAR)
RETURNS VOID AS'
DECLARE
C INTEGER;
P ALIAS FOR $1;
DUMMY=C2=A0 VARCHAR;
BEGIN=C2=A0=C2=A0=C2=A0
=C2=A0=C2=A0=C2=A0 C:=3D 0;
=C2=A0=C2=A0=C2=A0 LOOP
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 EXIT WHEN C > 15;
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 C:=3D C+1;
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 SELECT INTO DUMMY DBLINK_EXEC('&#= 39;CONNECTION_STRING TO DB3', ''UPDATE IN_FICHE_PRODUIT SET VALIDE =3D 1'');
=C2=A0=C2=A0=C2=A0 RAISE NOTICE ''%, %'', C,P;
=C2=A0=C2=A0=C2=A0 END LOOP;
END;'
LANGUAGE 'plpgsql';

Thanks for your time.


--0016e6d64cfccd19040488ff8e77-- From mmoncure@gmail.com Mon Jun 14 20:44:39 2010 Received: from maia.hub.org (maia-2.hub.org [200.46.204.251]) by mail.postgresql.org (Postfix) with ESMTP id 54924632293 for ; Mon, 14 Jun 2010 17:44:39 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.251]) (amavisd-maia, port 10024) with ESMTP id 22512-05 for ; Mon, 14 Jun 2010 20:44:27 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-vw0-f46.google.com (mail-vw0-f46.google.com [209.85.212.46]) by mail.postgresql.org (Postfix) with ESMTP id DBF11632281 for ; Mon, 14 Jun 2010 17:44:27 -0300 (ADT) Received: by vws13 with SMTP id 13so223735vws.19 for ; Mon, 14 Jun 2010 13:44:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:in-reply-to :references:date:message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=7fvBTnt6Smxs/PZFukI0FpaVdG15jMAldFblGjIjpYs=; b=XOfvakB4NScfNYDM8smnLFdgJX0CTy4kQ/jSIpmRzddxKuTsTMIFB3VXLYtZybgxk/ DuzgeFR8gmJcm55c+7yR8MTM/3ZCvNBBbIEhsnTpTjewmxIzzeEAVcQHYwo3SfdSWuwe mDWMTzZ+j8sHWMmuluvvItVJ/uduXBQ/S/Iqw= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; b=c9POi8RFskaS+yKwdLRbnoUkczPDbe+Kk6nN65a552kLXI9QH+6DlBFW1o5iam028t 5ALGKd0AWhJTD4zsG33M5GTO4mNuJTicFmAxq/S08QgtdbRMN68Qg/qK0FrJhzUHG7me SzCvPyc2GN/B6aJTm2Q1RjkVk0/J2RuWd+Ib4= MIME-Version: 1.0 Received: by 10.220.123.9 with SMTP id n9mr3136385vcr.129.1276548266527; Mon, 14 Jun 2010 13:44:26 -0700 (PDT) Received: by 10.220.87.67 with HTTP; Mon, 14 Jun 2010 13:44:26 -0700 (PDT) In-Reply-To: References: <4C164C9A.5030607@acteos.com> Date: Mon, 14 Jun 2010 16:44:26 -0400 Message-ID: Subject: Re: Fwd: Dead lock From: Merlin Moncure To: Dave Crooke Cc: Elias Ghanem , pgsql-performance@postgresql.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-1.9 tagged_above=-10 required=5 tests=BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001 X-Spam-Level: X-Archive-Number: 201006/252 X-Sequence-Number: 39108 On Mon, Jun 14, 2010 at 11:58 AM, Dave Crooke wrote: > If you're doing straight SQL bulk updates, then as someone suggested, you= could use an ORDER BY on a subquery, but I don't know if that is a guarant= ee, if you're not actually displaying the results then the DB may be techni= cally allowed to optimize it out from underneath you. The only way to be su= re is a cursor / procedure. 'order by' should be safe if you use SELECT...FOR UPDATE. update doesn't have an order by clause. Using cursor/procedure vs a query is not the material point; you have to make sure locks are acquired in a regular way. update foo set x=3Dx where id in (select * from bar order by x) does look dangerous. I think: update foo set x=3Dx where id in (select * from bar order by x for update) should be ok. I don't usually do it that way. merlin