summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>2010-10-12 02:46:38 +0100
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>2010-11-05 09:34:49 +0000
commita923a16ae8930594ea82a91ec04fc707182abfbe (patch)
treeec556d02ecdcf72080f59b9f6a94d4a4c025d06f
parent5dbeeba0f2760eb2344a34f1b25c952bfb4adb32 (diff)
downloadpsycopg2-a923a16ae8930594ea82a91ec04fc707182abfbe.tar.gz
Added two-phase commit docunetation.
-rw-r--r--doc/src/connection.rst156
-rw-r--r--doc/src/extensions.rst9
-rw-r--r--doc/src/usage.rst51
3 files changed, 215 insertions, 1 deletions
diff --git a/doc/src/connection.rst b/doc/src/connection.rst
index 787747a..df869bc 100644
--- a/doc/src/connection.rst
+++ b/doc/src/connection.rst
@@ -90,6 +90,7 @@ The ``connection`` class
.. _PgBouncer: http://pgbouncer.projects.postgresql.org/
+
.. index::
single: Exceptions; In the connection class
@@ -99,6 +100,157 @@ The ``connection`` class
available in the `psycopg2` module. See :ref:`dbapi-exceptions`.
+
+ .. index::
+ single: Two-phase commit; methods
+
+ .. rubric:: Two-phase commit support methods
+
+ .. versionadded:: 2.2.3
+
+ .. seealso:: :ref:`tpc` for an introductory explanation of these methods.
+
+ Note that PostgreSQL supports two-phase commit since release 8.1: these
+ methods raise `~psycopg2.NotSupportedError` if used with an older version
+ server.
+
+
+ .. _tpc_methods:
+
+ .. method:: xid(format_id, gtrid, bqual)
+
+ Returns a transaction ID object suitable for passing to the
+ `!tpc_*()` methods of this connection. The argument types and
+ constraints are explained in :ref:`tpc`.
+
+ The object returned can be accessed and unpacked as a 3 items tuple,
+ returning the arguments passed to the method. The same values are
+ available as attributes `!format_id`, `!gtrid`, `!bqual`.
+
+
+ .. method:: tpc_begin(xid)
+
+ Begins a TPC transaction with the given transaction ID *xid*.
+
+ This method should be called outside of a transaction (i.e. nothing
+ may have executed since the last `~connection.commit()` or
+ `~connection.rollback()` and `connection.status` is
+ `~psycopg2.extensions.STATUS_READY`).
+
+ Furthermore, it is an error to call `!commit()` or `!rollback()`
+ within the TPC transaction: in this case a `~psycopg2.ProgrammingError`
+ is raised.
+
+ The *xid* may be either an object returned by the `~connection.xid()`
+ method or a plain string: the latter allows to create a transaction
+ using the provided string as PostgreSQL transaction id. See also
+ `~connection.tpc_recover()`.
+
+
+ .. index::
+ pair: Transaction; Prepare
+
+ .. method:: tpc_prepare()
+
+ Performs the first phase of a transaction started with
+ `~connection.tpc_begin()`. A `~psycopg2.ProgrammingError` is raised if
+ this method is used outside of a TPC transaction.
+
+ After calling `!tpc_prepare()`, no statements can be executed until
+ `~connection.tpc_commit()` or `~connection.tpc_rollback()` have been
+ called. The `~connection.reset()` method can be used to restore the
+ status of the connection to `~psycopg2.extensions.STATUS_READY`: the
+ transaction will remained prepared in the database and will be
+ possible to finish it with `!tpc_commit(xid)` and
+ `!tpc_rollback(xid)`.
+
+ .. seealso:: the |PREPARE TRANSACTION|_ PostgreSQL command.
+
+ .. |PREPARE TRANSACTION| replace:: :sql:`PREPARE TRANSACTION`
+ .. _PREPARE TRANSACTION: http://www.postgresql.org/docs/9.0/static/sql-prepare-transaction.html
+
+
+ .. index::
+ pair: Commit; Prepared
+
+ .. method:: tpc_commit([xid])
+
+ When called with no arguments, `!tpc_commit()` commits a TPC
+ transaction previously prepared with `~connection.tpc_prepare()`.
+
+ If `!tpc_commit()` is called prior to `!tpc_prepare()`, a single phase
+ commit is performed. A transaction manager may choose to do this if
+ only a single resource is participating in the global transaction.
+
+ When called with a transaction ID *xid*, the database commits
+ the given transaction. If an invalid transaction ID is
+ provided, a `~psycopg2.ProgrammingError` will be raised. This form
+ should be called outside of a transaction, and is intended for use in
+ recovery.
+
+ On return, the TPC transaction is ended.
+
+ .. seealso:: the |COMMIT PREPARED|_ PostgreSQL command.
+
+ .. |COMMIT PREPARED| replace:: :sql:`COMMIT PREPARED`
+ .. _COMMIT PREPARED: http://www.postgresql.org/docs/9.0/static/sql-commit-prepared.html
+
+
+ .. index::
+ pair: Rollback; Prepared
+
+ .. method:: tpc_rollback([xid])
+
+ When called with no arguments, `!tpc_rollback()` rolls back a TPC
+ transaction. It may be called before or after
+ `~connection.tpc_prepare()`.
+
+ When called with a transaction ID *xid*, it rolls back the given
+ transaction. If an invalid transaction ID is provided, a
+ `~psycopg2.ProgrammingError` is raised. This form should be called
+ outside of a transaction, and is intended for use in recovery.
+
+ On return, the TPC transaction is ended.
+
+ .. seealso:: the |ROLLBACK PREPARED|_ PostgreSQL command.
+
+ .. |ROLLBACK PREPARED| replace:: :sql:`ROLLBACK PREPARED`
+ .. _ROLLBACK PREPARED: http://www.postgresql.org/docs/9.0/static/sql-rollback-prepared.html
+
+
+ .. index::
+ pair: Transaction; Recover
+
+ .. method:: tpc_recover()
+
+ Returns a list of pending transaction IDs suitable for use with
+ `!tpc_commit(xid)` or `!tpc_rollback(xid)`.
+
+ If a transaction was not initiated by Psycopg, the returned Xids will
+ have attributes `!format_id` and `!bqual` set to `None` and the
+ `!gtrid` set to the PostgreSQL transaction ID: such Xids are still
+ usable for recovery. Psycopg uses the same algorithm of the
+ `PostgreSQL JDBC driver`__ to encode a XA triple in a string, so
+ transactions initiated by a program using such driver should be
+ unpacked correctly.
+
+ .. __: http://jdbc.postgresql.org/
+
+ Xids returned by `!tpc_recover()` have additional attributes populated
+ with the values read from the server:
+
+ - `!prepared`: timestamp with timezone reporting the time the
+ transaction was prepared
+ - `!owner`: name of the user who prepared the transaction
+ - `!database`: name of the database the transaction belongs to
+
+ .. seealso:: the |pg_prepared_xacts|_ system view.
+
+ .. |pg_prepared_xacts| replace:: `pg_prepared_xacts`
+ .. _pg_prepared_xacts: http://www.postgresql.org/docs/9.0/static/view-pg-prepared-xacts.html
+
+
+
.. extension::
The above methods are the only ones defined by the |DBAPI| protocol.
@@ -118,7 +270,9 @@ The ``connection`` class
The method rolls back an eventual pending transaction and executes the
PostgreSQL |RESET|_ and |SET SESSION AUTHORIZATION|__ to revert the
- session to the default values.
+ session to the default values. A two-phase commit transaction prepared
+ using `~connection.tpc_prepare()` will remain in the database
+ available for recover.
.. |RESET| replace:: :sql:`RESET`
.. _RESET: http://www.postgresql.org/docs/9.0/static/sql-reset.html
diff --git a/doc/src/extensions.rst b/doc/src/extensions.rst
index ec93b2e..6517c70 100644
--- a/doc/src/extensions.rst
+++ b/doc/src/extensions.rst
@@ -450,6 +450,15 @@ internal usage and Python code should not rely on them.
An alias for `STATUS_BEGIN`
+.. data:: STATUS_PREPARED
+
+ The connection has been prepared for the second phase in a :ref:`two-phase
+ commit <tpc>` transaction. The connection can't be used to send commands
+ to the database until the transaction is finished with
+ `~connection.tpc_commit()` or `~connection.tpc_rollback()`.
+
+ .. versionadded:: 2.2.3
+
.. index::
diff --git a/doc/src/usage.rst b/doc/src/usage.rst
index 6528f6c..311e565 100644
--- a/doc/src/usage.rst
+++ b/doc/src/usage.rst
@@ -540,3 +540,54 @@ using the |lo_import|_ and |lo_export|_ libpq functions.
.. _lo_import: http://www.postgresql.org/docs/9.0/static/lo-interfaces.html#LO-IMPORT
.. |lo_export| replace:: `!lo_export()`
.. _lo_export: http://www.postgresql.org/docs/9.0/static/lo-interfaces.html#LO-EXPORT
+
+
+
+.. index::
+ pair: Two-phase commit; Transaction
+
+.. _tpc:
+
+Two-Phase Commit protocol support
+---------------------------------
+
+.. versionadded:: 2.2.3
+
+Psycopg exposes the two-phase commit features available from PostgreSQL 8,1
+implementing the *two-phase commit extensions* proposed by the |DBAPI|.
+
+The |DBAPI| model of two-phase commit is inspired to the `XA specification`__,
+according to which transaction IDs are formed from three components:
+
+- a format ID (non-negative 32 bit integer)
+- a global transaction ID (string not longer than 64 bytes)
+- a branch qualifier (string not longer than 64 bytes)
+
+For a particular global transaction, the first two components will be the same
+for all the resources. Every resource will be assigned a different branch
+qualifier.
+
+According to the |DBAPI| specification, a transaction ID is created using the
+`connection.xid()` method. Once you have a transaction id, a distributed
+transaction can be started with `connection.tpc_begin()`, prepared using
+`~connection.tpc_prepare()` and completed using `~connection.tpc_commit()` or
+`~connection.tpc_rollback()`. Transaction IDs can also be retrieved from the
+database using `~connection.tpc_recover()` and completed using the above
+`!tpc_commit()` and `!tpc_rollback()`.
+
+PostgreSQL doesn't follow the XA standard though, and the ID for a PostgreSQL
+prepared transaction can be any string up to 200 characters long. Psycopg can
+deal both with Xid objects created by the `!xid()` method and with
+transactions identified only by a string.
+
+The format in which the Xids are converted into strings passed to the
+database is the same employed by the `PostgreSQL JDBC driver`__: this should
+allow interoperation between tools written in Python and in Java. For example
+a recovery tool written in Python would be able to recognize the components of
+transactions produced by a Java program.
+
+For further details see the documentation for the above methods.
+
+.. __: http://www.opengroup.org/bookstore/catalog/c193.htm
+.. __: http://jdbc.postgresql.org/
+