简体   繁体   中英

ERROR: cannot execute nextval() in a read-only transaction - PostgreSQL

I can see internal server error on my app developed on spring mvc, using wildfly as the webserver and database is PostgreSQL . What does this exception mean?

ERROR: cannot execute nextval() in a read-only transaction

It was working all fine before. I tried to look for the solution here on stackoverflow but didn't find anything that could fix this issue.

The function nextval() is used to increment a sequence, which modifies the state of the database.

You get that error because you are in a read-only transaction. This can happen because

  1. You explicitly started a read-only transaction with START TRANSACTION READ ONLY or similar.

  2. The configuration parameter default_transaction_read_only is set to on .

  3. You are connected to a streaming replication standby server.

If default_transaction_read_only is set to on , you can either start a read-write transaction with

START TRANSACTION READ WRITE;

or change the setting by editing postgresql.conf or with the superuser command

ALTER SYSTEM SET default_transaction_read_only = off;

As others have pointed out nextval() actually updates the database to get a new sequence, so can't be used in a transaction that is marked as read only.

As you're using Spring I suspect this means that you're using the spring-transaction support. If you're using annotation based transaction support, then you'd get a read only transaction if you have

@Transactional(readOnly=true)

That means that when spring starts the transaction it will put it into read only mode.

Remove the readOnly=true bit and a regular writable transaction is created instead.

Spring transaction control at http://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/transaction.html

I means exactly what it says, here is example:

t=# create sequence so49;
CREATE SEQUENCE
t=# begin;
BEGIN
t=# select nextval('so49');
 nextval
---------
       1
(1 row)

t=# set transaction_read_only TO on;
SET
t=# select nextval('so49');
ERROR:  cannot execute nextval() in a read-only transaction
t=# end;
ROLLBACK

I presume you connected as so called ro user, which is user with "transaction_read_only" set to true, EG:

t=# select rolconfig from pg_roles where rolname ='ro';
         rolconfig
----------------------------
 {transaction_read_only=on}
(1 row)

you can switch that off for your user of course, but this is out of scope I believe

https://www.postgresql.org/docs/current/static/sql-set-transaction.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM