Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ne5jK-0000uX-3l for pgsql-admin@arkaria.postgresql.org; Tue, 12 Apr 2022 01:54:06 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1ne5jI-0000mu-O5 for pgsql-admin@arkaria.postgresql.org; Tue, 12 Apr 2022 01:54:04 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ne5jI-0000mf-6T for pgsql-admin@lists.postgresql.org; Tue, 12 Apr 2022 01:54:04 +0000 Received: from mail-qt1-x829.google.com ([2607:f8b0:4864:20::829]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1ne5jF-0007wP-Mv for pgsql-admin@lists.postgresql.org; Tue, 12 Apr 2022 01:54:03 +0000 Received: by mail-qt1-x829.google.com with SMTP id z15so8914951qtj.13 for ; Mon, 11 Apr 2022 18:54:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:date:mime-version:user-agent:subject:content-language:to :references:from:in-reply-to; bh=DvJOIeeDZaYxEh5bowO3lrfHug+zmXvIXWzinXvYOX8=; b=moZD2XNunplOfUOivDs2z2u9jAQ/a5RL3g4pcUKx+IDSGJyxVINsd1jXJ1fZDkTeaD B/37k7hkdt2XMk4BXpGQM73UuJFfHCRLZG5/9C1Xe6r61CQGMKTbksWE60awQI1I1Esn nEHJ/TBNhnCHfHHRv/mFvphZUFmodtlKmE/rhP2qDjWTjMLwUFcjdkaOQqitYCO8F4NU usNqBl3qFx9w9fPSudo2WbgywEXkwqznKeEKtUXvkZCwqTTCbzU9eOKZt+NkIovjJc8W wX7gPKVBsaJfZ1kH3OMnL64SQTyPqQSizgxOEzRyyfbdDT9v47OxFTNEd9xSjmmPn3kx MyUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:references:from:in-reply-to; bh=DvJOIeeDZaYxEh5bowO3lrfHug+zmXvIXWzinXvYOX8=; b=dLP+PBDwpebc699JUR5lHKG0ArHRw69VETO48LbFHOZ/aWlevGDNwgfEaW8QB4K7dG rLAJkmzpGbPl8Qn4P6dFG8IUj3pCH/RmE7hEg4RFSHla9cpAJ2p4awfyWoobwe1yourP wiEpjGouvUUCPosE0MHtLIqO3AerQXo9hjx/230YMR4idTRFe3KCmFTL31oN9QjCnTgm iKOUaoou4MMDHq3dG6CGCq8K36kdpR8EQX8OFKcF7l3M+1AEgb0bgYSJaPQb29BJW3ms Yt3jGa7U1wTPMPXlQGox3vZ7vIVJP8xX9D2d58n+mOzduuQtvCQwZOYucv1QDJxO4M6e YXAA== X-Gm-Message-State: AOAM531CIwKbfVbkj6z7VHzNXLyb7zlX+QoCYcBma9uh/hsWYKCKCkgj gS05RMKfKg8WphM1ho/tLdgYkeVzZX0saA== X-Google-Smtp-Source: ABdhPJyNMzw6yi0sBeN7B2aiLGaV89qudJ+Eii66dMhfJI2HeG+H4Rm7aocfinDgxpVhXaJXNFa23Q== X-Received: by 2002:a05:622a:593:b0:2e1:eabd:5e25 with SMTP id c19-20020a05622a059300b002e1eabd5e25mr1680673qtb.191.1649728440151; Mon, 11 Apr 2022 18:54:00 -0700 (PDT) Received: from [192.168.2.100] (pool-72-79-19-93.nwrknj.east.verizon.net. [72.79.19.93]) by smtp.gmail.com with ESMTPSA id p28-20020a05620a15fc00b0069c28de43casm2244446qkm.102.2022.04.11.18.53.59 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 11 Apr 2022 18:53:59 -0700 (PDT) Content-Type: multipart/alternative; boundary="------------DmX6Cz3hx3n3fa0gowcxHg0P" Message-ID: Date: Mon, 11 Apr 2022 21:53:59 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.7.0 Subject: Re: set autocommit only for select statements Content-Language: en-US To: pgsql-admin@lists.postgresql.org References: <548f2ed6-3209-705d-09e2-a5afbc6fb71c@quadratum-braccas.com> From: Mladen Gogala In-Reply-To: <548f2ed6-3209-705d-09e2-a5afbc6fb71c@quadratum-braccas.com> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk This is a multi-part message in MIME format. --------------DmX6Cz3hx3n3fa0gowcxHg0P Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit On 4/11/22 12:14, Sbob wrote: > Hi; > > > Is there a way to set "autocommit = on" for all select statements and > have "autocommit = off" for all other statements? > > > Thanks in advance > > > > The "autocommit" is a tool option which tells the tool whether to add "COMMIT" statement after each and every SQL. The RDBMS server only knows about transactions, as mandated by the ACID compliance. What the "autocommit" option of tools like psql actually does is to turn each of your SQL statements into a separate transaction. That can have some drawbacks, but it also has some positive sides. Your lock duration is much shorter and you don't get lock waits. However, some things may surprise you: [mgogala@umajor ~]$ psql Password for user mgogala: psql (13.6, server 14.2) WARNING: psql major version 13, server major version 14.          Some psql features might not work. Type "help" for help. mgogala=# select ename,sal from emp where deptno=20 for update;  ename | sal -------+------  SMITH |  800  JONES | 2975  SCOTT | 3000  ADAMS | 1100  FORD  | 3000 (5 rows) mgogala=# select l.locktype,d.datname,r.relname from pg_locks l join mgogala-# pg_database d on (l.database=d.oid) join pg_class r on (l.relation=r.oid);  locktype | datname |              relname ----------+---------+-----------------------------------  relation | mgogala | pg_class_tblspc_relfilenode_index  relation | mgogala | pg_class_relname_nsp_index  relation | mgogala | pg_class_oid_index  relation | mgogala | pg_class  relation | mgogala | pg_locks (5 rows) mgogala=# As you can see, I did "SELECT FOR UPDATE" from the table named "emp". When I check the locks from pg_locks, there are no locks on the "emp" table. That is because psql (and not the database) has executed "COMMIT" immediately after "SELECT FOR UPDATE", thereby ending the transaction and releasing the locks. However, if I open another session and do the following: mgogala=# begin transaction; BEGIN mgogala=*# select ename,sal from emp where deptno=20 for update;  ename | sal -------+------  SMITH |  800  JONES | 2975  SCOTT | 3000  ADAMS | 1100  FORD  | 3000 (5 rows) The result of query to pg_locks is now very different: mgogala=# select l.locktype,l.mode,d.datname,r.relname from pg_locks l join pg_database d on (l.database=d.oid) join pg_class r on (l.relation=r.oid);  locktype |      mode       | datname | relname ----------+-----------------+---------+----------------------------------- _*relation | RowShareLock    | mgogala | emp_pkey*__* *__* relation | RowShareLock    | mgogala | emp*_  relation | AccessShareLock | mgogala | pg_class_tblspc_relfilenode_index  relation | AccessShareLock | mgogala | pg_class_relname_nsp_index  relation | AccessShareLock | mgogala | pg_class_oid_index  relation | AccessShareLock | mgogala | pg_class  relation | AccessShareLock | mgogala | pg_locks (7 rows) Now, there are two locks in RowShare mode on the  emp table and its primary key. That is because the transaction on the "emp" table has not finished and locks are still intact. BTW, you don't have to turn off the autocommit mode to use "BEGIN TRANSACTION". The morals of the story is that the "autocommit option" is something that regulates the behavior of the tool, not the database. The point of "SELECT FOR UPDATE" is to lock certain rows in the database to modify them later. That will not work without "BEGIN TRANSACTION". In the autocommit mode, each SQL is a separate transaction, delineated by the transaction terminating statements by the tool executing the SQL. Regards -- Mladen Gogala Database Consultant Tel: (347) 321-1217 https://dbwhisperer.wordpress.com --------------DmX6Cz3hx3n3fa0gowcxHg0P Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit
On 4/11/22 12:14, Sbob wrote:
Hi;


Is there a way to set "autocommit = on" for all select statements and have "autocommit = off" for all other statements?


Thanks in advance




The "autocommit" is a tool option which tells the tool whether to add "COMMIT" statement after each and every SQL. The RDBMS server only knows about transactions, as mandated by the ACID compliance. What the "autocommit" option of tools like psql actually does is to turn each of your SQL statements into a separate transaction.  That can have some drawbacks, but it also has some positive sides. Your lock duration is much shorter and you don't get lock waits. However, some things may surprise you:

[mgogala@umajor ~]$ psql
Password for user mgogala:
psql (13.6, server 14.2)
WARNING: psql major version 13, server major version 14.
         Some psql features might not work.
Type "help" for help.

mgogala=# select ename,sal from emp where deptno=20 for update;
 ename | sal  
-------+------
 SMITH |  800
 JONES | 2975
 SCOTT | 3000
 ADAMS | 1100
 FORD  | 3000
(5 rows)

mgogala=# select l.locktype,d.datname,r.relname from pg_locks l join
mgogala-# pg_database d on (l.database=d.oid) join pg_class r on (l.relation=r.oid);
 locktype | datname |              relname              
----------+---------+-----------------------------------
 relation | mgogala | pg_class_tblspc_relfilenode_index
 relation | mgogala | pg_class_relname_nsp_index
 relation | mgogala | pg_class_oid_index
 relation | mgogala | pg_class
 relation | mgogala | pg_locks
(5 rows)

mgogala=#

As you can see, I did "SELECT FOR UPDATE" from the table named "emp". When I check the locks from pg_locks, there are no locks on the "emp" table. That is because psql (and not the database) has executed "COMMIT" immediately after "SELECT FOR UPDATE", thereby ending the transaction and releasing the locks. However, if I open another session and do the following:

mgogala=# begin transaction;
BEGIN
mgogala=*# select ename,sal from emp where deptno=20 for update;
 ename | sal  
-------+------
 SMITH |  800
 JONES | 2975
 SCOTT | 3000
 ADAMS | 1100
 FORD  | 3000
(5 rows)


The result of query to pg_locks is now very different:

mgogala=# select l.locktype,l.mode,d.datname,r.relname from pg_locks l join
pg_database d on (l.database=d.oid) join pg_class r on (l.relation=r.oid);
 locktype |      mode       | datname |              relname              
----------+-----------------+---------+-----------------------------------
 relation | RowShareLock    | mgogala | emp_pkey
 relation | RowShareLock    | mgogala | emp
 relation | AccessShareLock | mgogala | pg_class_tblspc_relfilenode_index
 relation | AccessShareLock | mgogala | pg_class_relname_nsp_index
 relation | AccessShareLock | mgogala | pg_class_oid_index
 relation | AccessShareLock | mgogala | pg_class
 relation | AccessShareLock | mgogala | pg_locks
(7 rows)

Now, there are two locks in RowShare mode on the  emp table and its primary key. That is because the transaction on the "emp" table has not finished and locks are still intact. BTW, you don't have to turn off the autocommit mode to use "BEGIN TRANSACTION". The morals of the story is that the "autocommit option" is something that regulates the behavior of the tool, not the database.

The point of "SELECT FOR UPDATE" is to lock certain rows in the database to modify them later. That will not work without "BEGIN TRANSACTION". In the autocommit mode, each SQL is a separate transaction, delineated by the transaction terminating statements by the tool executing the SQL.

Regards

-- 
Mladen Gogala
Database Consultant
Tel: (347) 321-1217
https://dbwhisperer.wordpress.com
--------------DmX6Cz3hx3n3fa0gowcxHg0P--