Commit cd339ce8 authored by Tim Peters's avatar Tim Peters

Merge rev 27526 from 3.3 branch.

Act as if a 3.3c1 release were being made.  Maybe it will
be.  Besides "the usual" release fiddling, repaired many
out-of-date pieces of the ZODB programming guide; I'm sure
many remain, though.
parent 4f8b410a
What's new in ZODB3 3.3 ?
=========================
Release date: DD-MMM-YYYY
What's new in ZODB3 3.3 release candidate 1?
============================================
Release date: 14-Sep-2004
Tools
-----
......@@ -20,12 +20,12 @@ Release date: DD-MMM-YYYY
Connection
----------
ZODB intends to raise ConnnectionStateError if an attempt is made to close
a connection while modifications are pending (the connection is involved in
a transaction that hasn't been ``abort()``'ed or ``commit()``'ed). It was
missing the case where the only pending modifications were made in
subtransactions. This has been fixed. If an attempt to close a connection
with pending subtransactions is made now::
ZODB intends to raise ``ConnnectionStateError`` if an attempt is made to
close a connection while modifications are pending (the connection is
involved in a transaction that hasn't been ``abort()``'ed or
``commit()``'ed). It was missing the case where the only pending
modifications were made in subtransactions. This has been fixed. If an
attempt to close a connection with pending subtransactions is made now::
ConnnectionStateError: Cannot close a connection with a pending subtransaction
......@@ -106,7 +106,7 @@ transaction
>>> ...
>>> txn.commit()
can't work as intended ib 3.3, because ``txn`` is no longer the current
can't work as intended in 3.3, because ``txn`` is no longer the current
``Transaction`` object the instant ``txn.begin()`` returns.
BTrees
......@@ -125,12 +125,12 @@ Collector #1488 (TemporaryStorage -- going backward in time). This
confusion was really due to that the detail on a ConflictError exception
didn't make sense. It called the current revision "was", and the old
revision "now". The detail is much more informative now. For example,
if the exception said:
if the exception said::
ConflictError: database conflict error (oid 0xcb22,
serial was 0x03441422948b4399, now 0x034414228c3728d5)
before, it now says:
before, it now says::
ConflictError: database conflict error (oid 0xcb22,
serial this txn started with 0x034414228c3728d5 2002-04-14 20:50:32.863000,
......@@ -146,20 +146,20 @@ the old serial).
Tools
-----
FileStorage.FileIterator was confused about how to read a transaction's
``FileStorage.FileIterator`` was confused about how to read a transaction's
user and description fields, which caused several tools to display
binary gibberish for these values.
ZODB.utils.oid_repr() changed to add a leading "0x", and to strip leading
zeroes. This is used, e.g., in the detail of a POSKeyError exception, to
identify the missing oid. Before, the output was ambiguous. For example,
oid 17 was displayed as 0000000000000011. As a Python integer, that's
octal 9. Or was it meant to be decimal 11? Or was it meant to be hex?
Now it displays as 0x11.
``ZODB.utils.oid_repr()`` changed to add a leading "0x", and to strip
leading zeroes. This is used, e.g., in the detail of a ``POSKeyError``
exception, to identify the missing oid. Before, the output was ambiguous.
For example, oid 17 was displayed as 0000000000000011. As a Python
integer, that's octal 9. Or was it meant to be decimal 11? Or was it
meant to be hex? Now it displays as 0x11.
fsrefs.py:
When run with -v, produced tracebacks for objects whose creation was
When run with ``-v``, produced tracebacks for objects whose creation was
merely undone. This was confusing. Tracebacks are now produced only
if there's "a real" problem loading an oid.
......@@ -171,13 +171,13 @@ fsrefs.py:
Now makes two passes, so that an accurate report can be given of all
invalid references.
analyze.py produced spurious "len of unsized object" messages when
``analyze.py`` produced spurious "len of unsized object" messages when
finding a data record for an object uncreation or version abort. These
no longer appear.
fsdump.py's get_pickle_metadata() function (which is used by several
``fsdump.py``'s ``get_pickle_metadata()`` function (which is used by several
tools) was confused about what to do when the ZODB pickle started with
a pickle GLOBAL opcode. It actually loaded the class then, which it
a pickle ``GLOBAL`` opcode. It actually loaded the class then, which it
intends never to do, leading to stray messages on stdout when the class
wasn't available, and leading to a strange return value even when it was
available (the repr of the type object was returned as "the module name",
......
ZODB3 3.3 beta 2
================
ZODB3 3.3 release candidate 1
=============================
Introduction
------------
......
......@@ -239,15 +239,25 @@ transaction.commit()
\end{verbatim}
The \module{transaction} module defines a few top-level functions for
working with transactions. \method{commit()} writes any modified
objects to disk, making the changes permanent. \method{abort()} rolls
working with transactions. \function{commit()} writes any modified
objects to disk, making the changes permanent. \function{abort()} rolls
back any changes that have been made, restoring the original state of
the objects. If you're familiar with database transactional
semantics, this is all what you'd expect. \method{get()} returns a
semantics, this is all what you'd expect. \function{get()} returns a
\class{Transaction} object that has additional methods like
\method{status()}, to check the current state of the transaction, and
\method{note()}, to add a note to the transaction metadata.
More precisely, the \module{transaction} module exposes an instance of
the \class{ThreadTransactionManager} transaction manager class as
\code{transaction.manager}, and the \module{transaction} functions
\function{get()} and \function{begin()} redirect to the same-named
methods of \code{transaction.manager}. The \function{commit()} and
\function{abort()} functions apply the methods of the same names to
the \class{Transaction} object returned by \code{transaction.manager.get()}.
This is for convenience. It's also possible to create your own transaction
manager instances, and to tell \code{DB.open()} to use your transaction
manager instead.
Because the integration with Python is so complete, it's a lot like
having transactional semantics for your program's variables, and you
can experiment with transactions at the Python interpreter's prompt:
......
......@@ -4,12 +4,36 @@
% Undoing
% Versions
% Multithreaded ZODB Programs
\section{Transactions and Versioning}
%\subsection{Committing and Aborting}
% XXX There seems very little to say about commit/abort...
\subsection{Committing and Aborting}
Changes made during a transaction don't appear in the database until
the transaction commits. This is done by calling the \method{commit()}
method of the current \class{Transaction} object, where the latter is
obtained from the \method{get()} method of the current transaction
manager. If the default thread transaction manager is being used, then
\code{transaction.commit()} suffices.
Similarly, a transaction can be explicitly aborted (all changes within
the transaction thrown away) by invoking the \method{abort()} method
of the current \class{Transaction} object, or simply
\code{transaction.abort()} if using the default thread transaction manager.
Prior to ZODB 3.3, if a commit failed (meaning the \code{commit()} call
raised an exception), the transaction was implicitly aborted and a new
transaction was implicitly started. This could be very surprising if the
exception was suppressed, and especially if the failing commit was one
in a sequence of subtransaction commits.
So, starting with ZODB 3.3, if a commit fails, all further attempts to
commit, join, or register with the transaction raise
\exception{ZODB.POSException.TransactionFailedError}. You must explicitly
start a new transaction then, either by calling the \method{abort()} method
of the current transaction, or by calling the \method{begin()} method of the
current transaction's transaction manager.
\subsection{Subtransactions}
......@@ -29,20 +53,20 @@ performed at intervals, say, every 10,000 objects. Those 10,000
objects are then written to permanent storage and can be purged from
the cache to free more space.
To commit a subtransaction instead of a full transaction,
To commit a subtransaction instead of a full transaction,
pass a true value to the \method{commit()}
or \method{abort()} method of the \class{Transaction} object.
\begin{verbatim}
# Commit a subtransaction
get_transaction().commit(1)
transaction.commit(True)
# Abort a subtransaction
get_transaction().abort(1)
transaction.abort(True)
\end{verbatim}
A new subtransaction is automatically started on committing or
aborting the previous subtransaction.
A new subtransaction is automatically started upon successful committing
or aborting the previous subtransaction.
\subsection{Undoing Changes}
......@@ -57,7 +81,7 @@ storage instance.
If a database supports undo, then the \method{undoLog(\var{start},
\var{end}\optional{, func})} method on the \class{DB} instance returns
the log of past transactions, returning transactions between the times
\var{start} and \var{end}, measured in seconds from the epoch.
\var{start} and \var{end}, measured in seconds from the epoch.
If present, \var{func} is a function that acts as a filter on the
transactions to be returned; it's passed a dictionary representing
each transaction, and only transactions for which \var{func} returns
......@@ -65,7 +89,7 @@ true will be included in the list of transactions returned to the
caller of \method{undoLog()}. The dictionary contains keys for
various properties of the transaction. The most important keys are
\samp{id}, for the transaction ID, and \samp{time}, for the time at
which the transaction was committed.
which the transaction was committed.
\begin{verbatim}
>>> print storage.undoLog(0, sys.maxint)
......@@ -83,7 +107,7 @@ which the transaction was committed.
To store a description and a user name on a commit, get the current
transaction and call the \method{note(\var{text})} method to store a
description, and the
\method{setUser(\var{user_name})} method to store the user name.
\method{setUser(\var{user_name})} method to store the user name.
While \method{setUser()} overwrites the current user name and replaces
it with the new value, the \method{note()} method always adds the text
to the transaction's description, so it can be called several times to
......@@ -91,8 +115,8 @@ log several different changes made in the course of a single
transaction.
\begin{verbatim}
get_transaction().setUser('amk')
get_transaction().note('Change ownership')
transaction.get().setUser('amk')
transaction.get().note('Change ownership')
\end{verbatim}
To undo a transaction, call the \method{DB.undo(\var{id})} method,
......@@ -115,6 +139,11 @@ that calls undo may not see the changes to the object until it calls
\subsection{Versions}
\begin{notice}[warning]
Versions should be avoided. They're going to be deprecated,
replaced by better approaches to long-running transactions.
\end{notice}
While many subtransactions can be contained within a single regular
transaction, it's also possible to contain many regular transactions
within a long-running transaction, called a version in ZODB
......@@ -155,7 +184,7 @@ different version or from an unversioned connection will cause a
from ZODB.POSException import VersionLockError
try:
get_transaction().commit()
transaction.commit()
except VersionLockError, (obj_id, version):
print ('Cannot commit; object %s '
'locked by version %s' % (obj_id, version))
......@@ -169,5 +198,5 @@ the version having a lock on it.
ZODB databases can be accessed from multithreaded Python programs.
The \class{Storage} and \class{DB} instances can be shared among
several threads, as long as individual \class{Connection} instances
are created for each thread.
are created for each thread.
......@@ -99,6 +99,7 @@ transaction:
\begin{verbatim}
from ZEO import ClientStorage
from ZODB import DB
import transaction
# Change next line to connect to your ZEO server
addr = 'kronos.example.com', 1975
......@@ -112,7 +113,7 @@ root['list'] = ['a', 'b', 1.0, 3]
root['dict'] = {'a':1, 'b':4}
# Commit the transaction
get_transaction().commit()
transaction.commit()
\end{verbatim}
If this code runs properly, then your ZEO server is working correctly.
......
\documentclass{howto}
\title{ZODB/ZEO Programming Guide}
\release{3.3b2}
\release{3.3c1}
\date{\today}
\author{A.M.\ Kuchling}
......
No preview for this file type
......@@ -218,7 +218,7 @@ class MyDistribution(Distribution):
doclines = __doc__.split("\n")
setup(name="ZODB3",
version="3.3b2",
version="3.3c1",
maintainer="Zope Corporation",
maintainer_email="zodb-dev@zope.org",
url = "http://www.zope.org/Wikis/ZODB",
......
......@@ -22,4 +22,4 @@ ZEO is now part of ZODB; ZODB's home on the web is
"""
# The next line must use double quotes, so release.py recognizes it.
version = "2.3b2"
version = "2.3c1"
......@@ -13,7 +13,7 @@
##############################################################################
# The next line must use double quotes, so release.py recognizes it.
__version__ = "3.3b2"
__version__ = "3.3c1"
import sys
import __builtin__
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment