AUTOCOMMIT mode is now an available backend GUC variable; setting it

to false provides more SQL-spec-compliant behavior than we had before.
I am not sure that setting it false is actually a good idea yet; there
is a lot of client-side code that will probably be broken by turning
autocommit off.  But it's a start.

Loosely based on a patch by David Van Wie.
This commit is contained in:
Tom Lane 2002-08-30 22:18:07 +00:00
parent 549928d99b
commit 26993b2918
15 changed files with 126 additions and 53 deletions

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.155 2002/08/30 00:28:40 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.156 2002/08/30 22:18:05 tgl Exp $
-->
<appendix id="release">
@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters.
-->
<literallayout><![CDATA[
No-autocommit mode is available (set autocommit to off)
Substantial improvements in functionality for functions returning sets
Client libraries older than 6.3 no longer supported (version 0 protocol removed)
PREPARE statement allows caching query plans for interactive statements

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.130 2002/08/30 16:50:49 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.131 2002/08/30 22:18:05 tgl Exp $
-->
<Chapter Id="runtime">
@ -1135,6 +1135,29 @@ env PGOPTIONS='-c geqo=off' psql
<para>
<variablelist>
<varlistentry>
<term><varname>AUTOCOMMIT</varname> (<type>bool</type>)</term>
<indexterm><primary>autocommit</></>
<listitem>
<para>
If set to true, <productname>PostgreSQL</productname> will
automatically do a <command>COMMIT</> after each successful command
that is not inside an explicit transaction block (that is, unless a
<command>BEGIN</> with no matching <command>COMMIT</> has been
given).
If set to false, <productname>PostgreSQL</productname> will commit
the effects of commands only on receiving an explicit
<command>COMMIT</> command. This mode can also be thought of as
implicitly issuing <command>BEGIN</> whenever a command is received
and <productname>PostgreSQL</productname> is not already inside
a transaction block.
The default is true, for compatibility with historical
<productname>PostgreSQL</productname> behavior. But for maximum
compatibility with the SQL specification, set it to false.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>AUSTRALIAN_TIMEZONES</varname> (<type>bool</type>)</term>
<indexterm><primary>Australian time zones</></>

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.130 2002/08/06 02:36:33 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.131 2002/08/30 22:18:05 tgl Exp $
*
* NOTES
* Transaction aborts can now occur two ways:
@ -220,10 +220,15 @@ TransactionState CurrentTransactionState = &CurrentTransactionStateData;
int DefaultXactIsoLevel = XACT_READ_COMMITTED;
int XactIsoLevel;
bool autocommit = true;
int CommitDelay = 0; /* precommit delay in microseconds */
int CommitSiblings = 5; /* number of concurrent xacts needed to
* sleep */
static bool suppressChain = false;
static void (*_RollbackFunc) (void *) = NULL;
static void *_RollbackData = NULL;
@ -1149,13 +1154,24 @@ CleanupTransaction(void)
/* --------------------------------
* StartTransactionCommand
*
* preventChain, if true, forces autocommit behavior at the next
* CommitTransactionCommand call.
* --------------------------------
*/
void
StartTransactionCommand(void)
StartTransactionCommand(bool preventChain)
{
TransactionState s = CurrentTransactionState;
/*
* Remember if caller wants to prevent autocommit-off chaining.
* This is only allowed if not already in a transaction block.
*/
suppressChain = preventChain;
if (preventChain && s->blockState != TBLOCK_DEFAULT)
elog(ERROR, "StartTransactionCommand: can't prevent chain");
switch (s->blockState)
{
/*
@ -1231,21 +1247,41 @@ StartTransactionCommand(void)
/* --------------------------------
* CommitTransactionCommand
*
* forceCommit = true forces autocommit behavior even when autocommit is off.
* --------------------------------
*/
void
CommitTransactionCommand(void)
CommitTransactionCommand(bool forceCommit)
{
TransactionState s = CurrentTransactionState;
switch (s->blockState)
{
/*
* if we aren't in a transaction block, we just do our usual
* transaction commit
* If we aren't in a transaction block, and we are doing
* autocommit, just do our usual transaction commit. But
* if we aren't doing autocommit, start a transaction block
* automatically by switching to INPROGRESS state. (We handle
* this choice here, and not earlier, so that an explicit BEGIN
* issued in autocommit-off mode won't issue strange warnings.)
*
* Autocommit mode is forced by either a true forceCommit parameter
* to me, or a true preventChain parameter to the preceding
* StartTransactionCommand call. This is needed so that commands
* like VACUUM can ensure that the right things happen.
*/
case TBLOCK_DEFAULT:
CommitTransaction();
if (autocommit || forceCommit || suppressChain)
CommitTransaction();
else
{
BeginTransactionBlock();
Assert(s->blockState == TBLOCK_INPROGRESS);
/* This code must match the TBLOCK_INPROGRESS case below: */
CommandCounterIncrement();
MemoryContextResetAndDeleteChildren(TransactionCommandContext);
}
break;
/*
@ -1406,7 +1442,10 @@ BeginTransactionBlock(void)
s->blockState = TBLOCK_BEGIN;
/*
* do begin processing
* do begin processing. NOTE: if you put anything here, check that
* it behaves properly in both autocommit-on and autocommit-off modes.
* In the latter case we will already have done some work in the new
* transaction.
*/
/*

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.50 2002/07/20 05:16:56 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.51 2002/08/30 22:18:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -55,7 +55,7 @@
static void
do_start()
{
StartTransactionCommand();
StartTransactionCommand(true);
elog(DEBUG3, "start transaction");
}
@ -63,7 +63,7 @@ do_start()
static void
do_end()
{
CommitTransactionCommand();
CommitTransactionCommand(true);
elog(DEBUG3, "commit transaction");
if (isatty(0))
{

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.138 2002/08/17 15:12:06 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.139 2002/08/30 22:18:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -448,7 +448,7 @@ BootstrapMain(int argc, char *argv[])
SetProcessingMode(BootstrapProcessing);
/* clean up processing */
StartTransactionCommand();
StartTransactionCommand(true);
cleanup();
/* not reached, here to make compiler happy */
@ -821,7 +821,7 @@ cleanup()
}
if (boot_reldesc != NULL)
closerel(NULL);
CommitTransactionCommand();
CommitTransactionCommand(true);
proc_exit(Warnings);
}

View File

@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.32 2002/08/29 00:17:02 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.33 2002/08/30 22:18:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1610,11 +1610,11 @@ RemoveTempRelationsCallback(void)
{
/* Need to ensure we have a usable transaction. */
AbortOutOfAnyTransaction();
StartTransactionCommand();
StartTransactionCommand(true);
RemoveTempRelations(myTempNamespace);
CommitTransactionCommand();
CommitTransactionCommand(true);
}
}

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.88 2002/08/05 03:29:16 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.89 2002/08/30 22:18:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -400,9 +400,9 @@ Async_UnlistenOnExit(void)
*/
AbortOutOfAnyTransaction();
/* Now we can do the unlisten */
StartTransactionCommand();
StartTransactionCommand(true);
Async_UnlistenAll();
CommitTransactionCommand();
CommitTransactionCommand(true);
}
/*
@ -749,7 +749,7 @@ ProcessIncomingNotify(void)
notifyInterruptOccurred = 0;
StartTransactionCommand();
StartTransactionCommand(true);
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel);
@ -803,7 +803,7 @@ ProcessIncomingNotify(void)
*/
heap_close(lRel, NoLock);
CommitTransactionCommand();
CommitTransactionCommand(true);
/*
* Must flush the notify messages to ensure frontend gets them

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.85 2002/08/29 15:56:20 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.86 2002/08/30 22:18:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -735,15 +735,16 @@ ReindexDatabase(const char *dbname, bool force, bool all)
heap_close(relationRelation, AccessShareLock);
/* Now reindex each rel in a separate transaction */
CommitTransactionCommand();
CommitTransactionCommand(true);
for (i = 0; i < relcnt; i++)
{
StartTransactionCommand();
StartTransactionCommand(true);
if (reindex_relation(relids[i], force))
elog(NOTICE, "relation %u was reindexed", relids[i]);
CommitTransactionCommand();
CommitTransactionCommand(true);
}
StartTransactionCommand();
/* Tell xact.c not to chain the upcoming commit */
StartTransactionCommand(true);
MemoryContextDelete(private_context);
}

View File

@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.234 2002/08/13 20:14:24 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.235 2002/08/30 22:18:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -273,7 +273,7 @@ vacuum(VacuumStmt *vacstmt)
}
/* matches the StartTransaction in PostgresMain() */
CommitTransactionCommand();
CommitTransactionCommand(true);
}
/*
@ -296,14 +296,14 @@ vacuum(VacuumStmt *vacstmt)
* return (else we leak memory while processing multiple tables).
*/
if (vacstmt->vacuum)
StartTransactionCommand();
StartTransactionCommand(true);
else
old_context = MemoryContextSwitchTo(anl_context);
analyze_rel(relid, vacstmt);
if (vacstmt->vacuum)
CommitTransactionCommand();
CommitTransactionCommand(true);
else
{
MemoryContextSwitchTo(old_context);
@ -319,8 +319,12 @@ vacuum(VacuumStmt *vacstmt)
{
/* here, we are not in a transaction */
/* matches the CommitTransaction in PostgresMain() */
StartTransactionCommand();
/*
* This matches the CommitTransaction waiting for us in PostgresMain().
* We tell xact.c not to chain the upcoming commit, so that a VACUUM
* doesn't start a transaction block, even when autocommit is off.
*/
StartTransactionCommand(true);
/*
* If we did a database-wide VACUUM, update the database's pg_database
@ -703,7 +707,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
Oid toast_relid;
/* Begin a transaction for vacuuming this relation */
StartTransactionCommand();
StartTransactionCommand(true);
/*
* Check for user-requested abort. Note we want this to be inside a
@ -719,7 +723,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
ObjectIdGetDatum(relid),
0, 0, 0))
{
CommitTransactionCommand();
CommitTransactionCommand(true);
return;
}
@ -750,7 +754,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
elog(WARNING, "Skipping \"%s\" --- only table or database owner can VACUUM it",
RelationGetRelationName(onerel));
relation_close(onerel, lmode);
CommitTransactionCommand();
CommitTransactionCommand(true);
return;
}
@ -763,7 +767,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
elog(WARNING, "Skipping \"%s\" --- can not process indexes, views or special system tables",
RelationGetRelationName(onerel));
relation_close(onerel, lmode);
CommitTransactionCommand();
CommitTransactionCommand(true);
return;
}
@ -799,7 +803,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
/*
* Complete the transaction and free all temporary memory used.
*/
CommitTransactionCommand();
CommitTransactionCommand(true);
/*
* If the relation has a secondary toast rel, vacuum that too while we

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.286 2002/08/29 23:39:05 inoue Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.287 2002/08/30 22:18:06 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@ -860,7 +860,7 @@ static void
start_xact_command(void)
{
elog(DEBUG1, "StartTransactionCommand");
StartTransactionCommand();
StartTransactionCommand(false);
}
static void
@ -872,7 +872,7 @@ finish_xact_command(void)
/* Now commit the command */
elog(DEBUG1, "CommitTransactionCommand");
CommitTransactionCommand();
CommitTransactionCommand(false);
#ifdef SHOW_MEMORY_STATS
/* Print mem stats at each commit for leak tracking */
@ -1664,7 +1664,7 @@ PostgresMain(int argc, char *argv[], const char *username)
if (!IsUnderPostmaster)
{
puts("\nPOSTGRES backend interactive interface ");
puts("$Revision: 1.286 $ $Date: 2002/08/29 23:39:05 $\n");
puts("$Revision: 1.287 $ $Date: 2002/08/30 22:18:06 $\n");
}
/*

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.111 2002/08/29 21:02:12 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.112 2002/08/30 22:18:06 tgl Exp $
*
*
*-------------------------------------------------------------------------
@ -330,7 +330,7 @@ InitPostgres(const char *dbname, const char *username)
/* start a new transaction here before access to db */
if (!bootstrap)
StartTransactionCommand();
StartTransactionCommand(true);
/*
* It's now possible to do real access to the system catalogs.
@ -394,7 +394,7 @@ InitPostgres(const char *dbname, const char *username)
/* close the transaction we started above */
if (!bootstrap)
CommitTransactionCommand();
CommitTransactionCommand(true);
/*
* Check a normal user hasn't connected to a superuser reserved slot.

View File

@ -5,7 +5,7 @@
* command, configuration file, and command line options.
* See src/backend/utils/misc/README for more information.
*
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.88 2002/08/30 16:50:50 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.89 2002/08/30 22:18:07 tgl Exp $
*
* Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
@ -58,6 +58,7 @@ extern int PreAuthDelay;
extern int AuthenticationTimeout;
extern int StatementTimeout;
extern int CheckPointTimeout;
extern bool autocommit;
extern int CommitDelay;
extern int CommitSiblings;
extern bool FixBTree;
@ -487,6 +488,10 @@ static struct config_bool
{ "db_user_namespace", PGC_SIGHUP }, &Db_user_namespace,
false, NULL, NULL
},
{
{ "autocommit", PGC_USERSET }, &autocommit,
true, NULL, NULL
},
{
{ NULL, 0 }, NULL, false, NULL, NULL

View File

@ -68,8 +68,6 @@
#checkpoint_segments = 3 # in logfile segments, min 1, 16MB each
#checkpoint_timeout = 300 # range 30-3600, in seconds
#
#wal_files = 0 # range 0-64
#
#commit_delay = 0 # range 0-100000, in microseconds
#commit_siblings = 5 # range 1-1000
#
@ -186,6 +184,7 @@
#
# Misc
#
#autocommit = true
#dynamic_library_path = '$libdir'
#search_path = '$user,public'
#datestyle = 'iso, us'

View File

@ -3,7 +3,7 @@
*
* Copyright 2000-2002 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.59 2002/08/30 18:15:23 momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.60 2002/08/30 22:18:07 tgl Exp $
*/
/*----------------------------------------------------------------------
@ -246,6 +246,7 @@ psql_completion(char *text, int start, int end)
"australian_timezones",
"password_encryption",
"transform_null_equals",
"autocommit",
"default_statistics_target",
"geqo_threshold",

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: xact.h,v 1.44 2002/06/20 20:29:43 momjian Exp $
* $Id: xact.h,v 1.45 2002/08/30 22:18:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -105,8 +105,8 @@ extern AbsoluteTime GetCurrentTransactionStartTimeUsec(int *usec);
extern bool TransactionIdIsCurrentTransactionId(TransactionId xid);
extern bool CommandIdIsCurrentCommandId(CommandId cid);
extern void CommandCounterIncrement(void);
extern void StartTransactionCommand(void);
extern void CommitTransactionCommand(void);
extern void StartTransactionCommand(bool preventChain);
extern void CommitTransactionCommand(bool forceCommit);
extern void AbortCurrentTransaction(void);
extern void BeginTransactionBlock(void);
extern void EndTransactionBlock(void);