summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-01-20 04:47:16 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-01-20 04:47:16 +0000
commitef63a84a4958f987b841cd8034c66fec22bb03ed (patch)
tree7b9afd0b89bd6fffdf8f0d3256c47db1a63d9314
parente15f6c7327588bc11bb73ba1535ecf8e88791e02 (diff)
downloadsqlalchemy-ef63a84a4958f987b841cd8034c66fec22bb03ed.tar.gz
further clarification on transaction state
-rw-r--r--doc/build/content/session.txt35
1 files changed, 28 insertions, 7 deletions
diff --git a/doc/build/content/session.txt b/doc/build/content/session.txt
index d44bef50d..b8978302e 100644
--- a/doc/build/content/session.txt
+++ b/doc/build/content/session.txt
@@ -339,6 +339,8 @@ This second form of flush should be used carefully as it will not necessarily lo
Theres also a way to have `flush()` called automatically before each query; this is called "autoflush" and is described below.
+Note that when using a `Session` that has been placed into a transaction, the `commit()` method will also `flush()` the `Session` unconditionally before committing the transaction.
+
Note that flush **does not change** the state of any collections or entity relationships in memory; for example, if you set a foreign key attribute `b_id` on object `A` with the the identifier `B.id`, the change will be flushed to the database, but `A` will not have `B` added to its collection. If you want to manipulate foreign key attributes directly, `refresh()` or `expire()` the objects whose state needs to be refreshed subsequent to flushing.
### Autoflush
@@ -360,6 +362,14 @@ A session can be configured to issue `flush()` calls before each query. This al
Autoflush is particularly handy when using "dynamic" mapper relations, so that changes to the underlying collection are immediately available via its query interface.
+### Committing
+
+The `commit()` method on `Session` is used specifically when the `Session` is in a transactional state. The two ways that a session may be placed in a transactional state are to create it using the `transactional=True` option, or to call the `begin()` method.
+
+`commit()` serves **two** purposes; it issues a `flush()` unconditionally to persist any remaining pending changes, and it issues a commit to all currently managed database connections. In the typical case this is just a single connection. After the commit, connection resources which were allocated by the `Session` are released. This holds true even for a `Session` which specifies `transactional=True`; when such a session is committed, the next transaction is not "begun" until the next database operation occurs.
+
+See the section below on "Managing Transactions" for further detail.
+
### Expunge / Clear
Expunge removes an object from the Session, sending persistent instances to the detached state, and pending instances to the transient state:
@@ -440,14 +450,23 @@ The easiest way to use a Session with transactions is just to declare it as tran
# transactional session
Session = sessionmaker(transactional=True)
sess = Session()
- item1 = sess.query(Item).get(1)
- item2 = sess.query(Item).get(2)
- item1.foo = 'bar'
- item2.bar = 'foo'
-
- # commit- will immediately go into a new transaction afterwards
- sess.commit()
+ try:
+ item1 = sess.query(Item).get(1)
+ item2 = sess.query(Item).get(2)
+ item1.foo = 'bar'
+ item2.bar = 'foo'
+ # commit- will immediately go into a new transaction afterwards
+ sess.commit()
+ except:
+ # rollback - will immediately go into a new transaction afterwards.
+ sess.rollback()
+
+Things to note above:
+
+ * When using a transactional session, either a `rollback()` or a `close()` call **is required** when an error is raised by `flush()` or `commit()`. The `flush()` error condition will issue a ROLLBACK to the database automatically, but the state of the `Session` itself remains in an "undefined" state until the user decides whether to rollback or close.
+ * The `commit()` call unconditionally issues a `flush()`. Particularly when using `transactional=True` in conjunction with `autoflush=True`, explicit `flush()` calls are usually not needed.
+
Alternatively, a transaction can be begun explicitly using `begin()`:
{python}
@@ -465,6 +484,8 @@ Alternatively, a transaction can be begun explicitly using `begin()`:
sess.rollback()
raise
+Like the `transactional` example, the same rules apply; an explicit `rollback()` or `close()` is required when an error occurs, and the `commit()` call issues a `flush()` as well.
+
Session also supports Python 2.5's with statement so that the example above can be written as:
{python}