<para>Spring resolves the disadvantages of global and local
<para>With programmatic transaction management, developers work with the
transactions. It enables application developers to use a
Spring Framework transaction abstraction, which can run over any
<emphasis>consistent</emphasis> programming model <emphasis>in any
underlying transaction infrastructure. With the preferred declarative
environment</emphasis>. You write your code once, and it can benefit
model, developers typically write little or no code related to transaction
from different transaction management strategies in different
management, and hence don't depend on the Spring Framework's transaction
environments. Spring Framework provides both declarative and
API (or indeed on any other transaction API).</para>
programmatic transaction management. Most users prefer declarative
transaction management, which is recommended in most cases.</para>
<!--Do you need to specify that Spring allows you to work with *multiple* transactional resourcess (as global transactions do)?-->
<para>With programmatic transaction management, developers work with the
Spring Framework transaction abstraction, which can run over any
underlying transaction infrastructure. <!--Re preceding statement, does this mean that next section re transaction abstraction applies only to programmatic tx management?If so--><!--shouldn't the next section be subsection of *Programmatic transaction management* section? However, there is a sentence in the next--><!--section that reads *regardless of whether you opt for declarative or prog. tx man. defining correct PlatformTransactionManager impl. is--><!--absolutely essential.* This is followed by discussion of that impl. So I'm not sure what goes where.
TR: I think it's fine as is - the concepts apply to both programmatic and declarative transactions
-->With the preferred declarative model, developers typically write little or
no code related to transaction management, and hence do not depend on
the Spring Framework transaction API, or any other transaction
API.</para>
<sidebar>
<title>Do you need an application server for transaction
management?</title>
<para>Spring Framework's transaction management support changes
traditional rules as to when a Java EE application requires an
application server.</para>
<para>In particular, you do not need an application server simply for
declarative transactions through EJBs. In fact, even if your
application server has powerful JTA capabilities, you may decide that
the Spring Framework's declarative transactions offer more power and a
more productive programming model than EJB CMT.</para>
<para>Typically you need an application server's JTA capability only
if your application needs to handle transactions across multiple
resources, which is not a requirement for many applications. Many
high-end applications use a single, highly scalable database (such as
Oracle RAC) instead. Standalone transaction managers such as <ulink
url="http://www.atomikos.com/">Atomikos Transactions</ulink> and
<ulinkurl="http://jotm.objectweb.org/">JOTM</ulink> are other
options. Of course, you may need other application server capabilities
such as Java Message Service (JMS) and J2EE Connector Architecture
(JCA).</para>
<para>Spring Framework <emphasis>gives you the choice of when to scale
your application to a fully loaded application server</emphasis>. Gone
are the days when the only alternative to using EJB CMT or JTA was to
write code with local transactions such as those on JDBC connections,
and face a hefty rework if you need that code to run within global,
container-managed transactions. With Spring Framework, only some of
the bean definitions in your configuration file, rather than your
code, needs to change.</para>
<!--CLarify last sentence. Only what kind of configuration has to change?
TR: changed to say "some of the bean definitions in your configuration file"-->
</sidebar>
</section>
</section>
</section>
<sectionid="transaction-strategies">
<sectionid="transaction-strategies">
<title>Key abstractions</title>
<title>Understanding the Spring Framework transaction abstraction<!--If this section applies only to prog. tx management, we should say that up front. Add info? TR: It's relevant for declarative tx as well--></title>
<para>The key to the Spring transaction abstraction is the notion of a
<para>The key to the Spring transaction abstraction is the notion of a
<emphasis>transaction strategy</emphasis>. A transaction strategy is
<emphasis>transaction strategy</emphasis>. A transaction strategy is
are defined like any other object (or bean) in the Spring Framework's IoC
are defined like any other object (or bean) in the Spring Framework IoC
container. This benefit alone makes it a worthwhile abstraction even when
container. This benefit alone makes Spring Framework transactions a
working with JTA: transactional code can be tested much more easily than
worthwhile abstraction even when you work with JTA. Transactional code can
if it used JTA directly.</para>
be tested much more easily than if it used JTA directly.</para>
<para>Again in keeping with Spring's philosophy, the
<para>Again in keeping with Spring's philosophy, the
<exceptionname>TransactionException</exceptionname> that can be thrown by
<exceptionname>TransactionException</exceptionname> that can be thrown by
any of the <interfacename>PlatformTransactionManager</interfacename>
any of the <interfacename>PlatformTransactionManager</interfacename>
interface's methods is <emphasis>unchecked</emphasis> (that is it extends
interface's methods is <emphasis>unchecked</emphasis> (that is, it extends
the <exceptionname>java.lang.RuntimeException</exceptionname> class).
the <exceptionname>java.lang.RuntimeException</exceptionname> class).
Transaction infrastructure failures are almost invariably fatal. In rare
Transaction infrastructure failures are almost invariably fatal. In rare
cases where application code can actually recover from a transaction
cases where application code can actually recover from a transaction
...
@@ -228,56 +252,57 @@
...
@@ -228,56 +252,57 @@
<interfacename>TransactionStatus</interfacename> object, depending on a
<interfacename>TransactionStatus</interfacename> object, depending on a
<interfacename>TransactionDefinition</interfacename> parameter. The
<interfacename>TransactionDefinition</interfacename> parameter. The
returned <interfacename>TransactionStatus</interfacename> might represent
returned <interfacename>TransactionStatus</interfacename> might represent
a new or existing transaction (if there were a matching transaction in the
a new transaction, or can represent an existing transaction if a matching
current call stack - with the implication being that (as with J2EE
transaction exists in the current call stack. The implication in this
transaction contexts) a <interfacename>TransactionStatus</interfacename>
latter case is that, as with Java EE transaction contexts, a
is associated with a <emphasisrole="bold">thread</emphasis> of
<interfacename>TransactionStatus</interfacename> is associated with a
execution).</para>
<emphasisrole="bold">thread</emphasis> of execution.<!--Previous sentences were difficult to follow because of all the parenthetical phrases.Revise if necessary.--></para>
<interfacename>PlatformTransactionManager</interfacename>.<!--I broke into two sentences. Last part of sentence unclear,revise to say what triggers tx synch. Revise sentences if necessray.--></para>
transaction aware factory beans or proxies for managing the native
synchronization of the resources and exception mapping so that user data
resource factories. These transaction aware solutions internally handle
access code doesn't have to worry about these concerns at all, but can
resource creation and reuse, cleanup, optional transaction
concentrate purely on non-boilerplate persistence logic. Generally, the
synchronization of the resources, and exception mapping. Thus user data
same <emphasis>template</emphasis> approach is used for all persistence
access code does not have to address these tasks, but can be focused
APIs, with examples including the <classname>JdbcTemplate</classname>,
purely on non-boilerplate persistence logic. Generally, you use the
<classname>HibernateTemplate</classname>, and
native ORM API or a <emphasis>template</emphasis> approach for JDBC
<classname>JdoTemplate</classname> classes (detailed in subsequent
access using the <classname>JdbcTemplate</classname>. All of these
chapters of this reference documentation.</para>
solutions are detailed in subsequent chapters of this reference
documentation.<!--If this approach is preferred, why not give examples here as you do with less desirable approaches? At least provide--><!--x-refs? Also is it correct to refer to APIs, then give classes as examples? Should this be reworded?
TR: I re-wrote this to match the current preferred approaches--></para>
</section>
</section>
<sectionid="tx-resource-synchronization-low">
<sectionid="tx-resource-synchronization-low">
<title>Low-level approach</title>
<title>Low-level synchronization approach</title>
<para>At a lower level exist classes such as
<para>Classes such as <classname>DataSourceUtils</classname> (for JDBC),
<para>If an existing transaction exists, and already has a connection
<para>If an existing transaction already has a connection synchronized
synchronized (linked) to it, that instance will be returned. Otherwise,
(linked) to it, that instance is returned. Otherwise, the method call
the method call will trigger the creation of a new connection, which
triggers the creation of a new connection, which is (optionally)
will be (optionally) synchronized to any existing transaction, and made
synchronized to any existing transaction, and made available for
available for subsequent reuse in that same transaction. As mentioned,
subsequent reuse in that same transaction. As mentioned, any
this has the added advantage that any
<exceptionname>SQLException</exceptionname> is wrapped in a Spring
<exceptionname>SQLException</exceptionname> will be wrapped in a Spring
Framework
Framework
<exceptionname>CannotGetJdbcConnectionException</exceptionname> - one of
<exceptionname>CannotGetJdbcConnectionException</exceptionname>, one of
the Spring Framework's hierarchy of unchecked DataAccessExceptions. This
the Spring Framework's hierarchy of unchecked DataAccessExceptions. This
gives you more information than can easily be obtained from the
approach gives you more information than can be obtained easily from the
<exceptionname>SQLException</exceptionname>, and ensures portability
<exceptionname>SQLException</exceptionname>, and ensures portability
across databases: even across different persistence technologies.</para>
across databases, even across different persistence technologies.</para>
<para>It should be noted that this will also work fine without Spring
<para>This approach also works without Spring transaction management
transaction management (transaction synchronization is optional), so you
(transaction synchronization is optional), so you can use it whether or
can use it whether or not you are using Spring for transaction
not you are using Spring for transaction management.</para>
management.</para>
<para>Of course, once you've used Spring's JDBC support or Hibernate
<para>Of course, once you have used Spring's JDBC support, JPA support
support, you will generally prefer not to use
or Hibernate support, you will generally prefer not to use
<classname>DataSourceUtils</classname> or the other helper classes,
<classname>DataSourceUtils</classname> or the other helper classes,
because you'll be much happier working via the Spring abstraction than
because you will be much happier working through the Spring abstraction
directly with the relevant APIs. For example, if you use the Spring
than directly with the relevant APIs. For example, if you use the Spring
<classname>JdbcTemplate</classname> or <literal>jdbc.object</literal>
<classname>JdbcTemplate</classname> or <literal>jdbc.object</literal>
package to simplify your use of JDBC, correct connection retrieval
package to simplify your use of JDBC, correct connection retrieval
happens behind the scenes and you won't need to write any special
occurs behind the scenes and you won't need to write any special
code.</para>
code.</para>
<!--I don't understand this. Why tell them to use DataSourceUtils and then say you will prefer Spring abstraction? Why not give example of using Spring abstraction?-->
</section>
</section>
<sectionid="tx-resource-synchronization-tadsp">
<sectionid="tx-resource-synchronization-tadsp">
...
@@ -519,74 +563,73 @@
...
@@ -519,74 +563,73 @@
wraps the target <interfacename>DataSource</interfacename> to add
wraps the target <interfacename>DataSource</interfacename> to add
awareness of Spring-managed transactions. In this respect, it is similar
awareness of Spring-managed transactions. In this respect, it is similar
to a transactional JNDI <interfacename>DataSource</interfacename> as
to a transactional JNDI <interfacename>DataSource</interfacename> as
provided by a J2EE server.</para>
provided by a Java EE server.<!--What is the purpose of TransactionAwareDataSourceProxy, do you use it instead of 4.2 or 4.1 approaches or in addition to?--></para>
<para>It should almost never be necessary or desirable to use this
<para>It should almost never be necessary or desirable to use this
class, except when existing code exists which must be called and passed
class, except when existing code must be called and passed a standard
a standard JDBC <interfacename>DataSource</interfacename> interface
<para>The Spring Framework's declarative transaction management is made
</note>
possible with Spring AOP, although, as the transactional aspects code
comes with the Spring Framework distribution and may be used in a
<para>Spring Framework's declarative transaction management is made
boilerplate fashion, AOP concepts do not generally have to be understood
possible with Spring aspect-oriented programming (AOP), although, as the
to make effective use of this code.</para>
transactional aspects code comes with the Spring Framework distribution
and may be used in a boilerplate fashion, AOP concepts do not generally
<para>It may be helpful to begin by considering EJB CMT and explaining the
have to be understood to make effective use of this code.</para>
similarities and differences with the Spring Framework's declarative
transaction management. The basic approach is similar: it is possible to
<para>Spring Framework's declarative transaction management is similar to
specify transaction behavior (or lack of it) down to individual method
EJB CMT in that you can specify transaction behavior (or lack of it) down
level. It is possible to make a <methodname>setRollbackOnly()</methodname>
to individual method level. It is possible to make a
call within a transaction context if necessary. The differences
<methodname>setRollbackOnly()</methodname> call within a transaction
are:</para>
context if necessary. The differences between the two types of transaction
management are:</para>
<itemizedlist>
<itemizedlist>
<listitem>
<listitem>
<para>Unlike EJB CMT, which is tied to JTA, the Spring Framework's
<para>Unlike EJB CMT, which is tied to JTA, Spring Framework's
declarative transaction management works in any environment. It can
declarative transaction management works in any environment. It can
work with JDBC, JDO, Hibernate or other transactions under the covers,
work with JTA transactions or local transactions using JDBC, JPA,
with configuration changes only.</para>
Hibernate or JDO by simple adjusting the configuration files.<!--Indicate what kind of config changes? Changes to what TR: rewrote this to hoefully make it more clear--></para>
</listitem>
</listitem>
<listitem>
<listitem>
<para>The Spring Framework enables declarative transaction management
<para>You can apply Spring Framework declarative transaction
to be applied to any class, not merely special classes such as
management to any class, not merely special classes such as
EJBs.</para>
EJBs.</para>
</listitem>
</listitem>
<listitem>
<listitem>
<para>The Spring Framework offers declarative <link
<para><emphasis>(This example assumes that all your service interfaces
<para><note>
are defined in the <literal>'x.y.service'</literal> package; see the
<para><emphasis>In this example it is assumed that all your service
chapter entitled <xreflinkend="aop"/> for more
interfaces are defined in the <literal>x.y.service</literal>
details.)</emphasis></para>
package; see <xreflinkend="aop"/> for more
details.</emphasis></para>
</note></para>
<para>Now that we've analyzed the configuration, you may be asking
<para>Now that we've analyzed the configuration, you may be asking
yourself, <quote><emphasis>Okay... but what does all this configuration
yourself, <quote><emphasis>Okay... but what does all this configuration
actually do?</emphasis></quote>.</para>
actually do?</emphasis></quote>.</para>
<para>The above configuration is going to effect the creation of a
<para>The above configuration will be used to create a transactional
transactional proxy around the object that is created from the
proxy around the object that is created from the
<literal>'fooService'</literal> bean definition. The proxy will be
<literal>fooService</literal> bean definition. <!--Clarify what you mean by around the object; do you mean associated with the object? Revise to clarify. Around is vague.-->The
configured with the transactional advice, so that when an appropriate
proxy will be configured with the transactional advice, so that when an
method is invoked <emphasis>on the proxy</emphasis>, a transaction
appropriate method is invoked <emphasis>on the proxy</emphasis>, a
<emphasis>may</emphasis> be started, suspended, be marked as read-only,
transaction is started, suspended, marked as read-only, and so on,
etc., depending on the transaction configuration associated with that
depending on the transaction configuration associated with that method.
method. Consider the following program that test drives the above
Consider the following program that test drives the above
configuration.</para>
configuration:</para>
<programlistinglanguage="java">public final class Boot {
<programlistinglanguage="java">public final class Boot {
...
@@ -880,12 +918,10 @@ public class DefaultFooService implements FooService {
...
@@ -880,12 +918,10 @@ public class DefaultFooService implements FooService {
}
}
}</programlisting>
}</programlisting>
<para>The output from running the above program will look something like
<para>The output from running the preceding program will resemble the
this. <emphasis>(Please note that the Log4J output and the stacktrace
following. (The Log4J output and the stack trace from the
from the <exceptionname>UnsupportedOperationException</exceptionname>
UnsupportedOperationException thrown by the insertFoo(..) method of the
thrown by the <methodname>insertFoo(..)</methodname> method of the
DefaultFooService class have been truncated for clarity.)</para>
<classname>DefaultFooService</classname> class have been truncated in
the interest of clarity.)</emphasis></para>
<programlistinglanguage="xml"><lineannotation><emphasisrole="bold"><!-- the Spring container is starting up... --></emphasis></lineannotation>
<programlistinglanguage="xml"><lineannotation><emphasisrole="bold"><!-- the Spring container is starting up... --></emphasis></lineannotation>
<title>Rolling back a declarative transaction</title>
<para>The previous section outlined the basics of how to specify the
<para>The previous section outlined the basics of how to specify
transactional settings for the classes, typically service layer classes,
transactional settings for classes, typically service layer classes,
in your application in a declarative fashion. This section describes how
declaratively in your application. This section describes how you can
you can control the rollback of transactions in a simple declarative
control the rollback of transactions in a simple declarative
fashion.</para>
fashion.</para>
<para>The recommended way to indicate to the Spring Framework's
<para>The recommended way to indicate to Spring Framework's transaction
transaction infrastructure that a transaction's work is to be rolled
infrastructure that a transaction's work is to be rolled back is to
back is to throw an <exceptionname>Exception</exceptionname> from code
throw an <exceptionname>Exception</exceptionname> from code that is
that is currently executing in the context of a transaction. The Spring
currently executing in the context of a transaction. Spring Framework's
Framework's transaction infrastructure code will catch any unhandled
transaction infrastructure code, in its default configuration, will
<exceptionname>Exception</exceptionname> as it bubbles up the call
catch any unhandled <exceptionname>Exception</exceptionname> as it
stack, and will mark the transaction for rollback.</para>
bubbles up the call stack, and mark the transaction for rollback.<!--I changed to *can be configured* because next sentence says it does not do this by default in all cases.
TR: I changed it to *in its default configuration*--></para>
<para>Note however that the Spring Framework's transaction
infrastructure code will, by default, <emphasis>only</emphasis> mark a
<para>However, Spring Framework's transaction infrastructure code, by
transaction for rollback in the case of runtime, unchecked exceptions;
default, <emphasis>only</emphasis> mark a transaction for rollback in
that is, when the thrown exception is an instance or subclass of
the case of runtime, unchecked exceptions; that is, when the thrown
exception is an instance or subclass of
<exceptionname>RuntimeException</exceptionname>.
<exceptionname>RuntimeException</exceptionname>.
(<literal>Errors</literal> will also - by default - result in a
(<exceptionname>Error</exceptionname>s will also - by default - result
rollback.) Checked exceptions that are thrown from a transactional
in a rollback). Checked exceptions that are thrown from a transactional
method will <emphasis>not</emphasis> result in the transaction being
method do <emphasis>not</emphasis> result in rollback.<!--I revised preceding because it says ONLY first case is rolled back by default, but then says Errors are also marked by default.
rolled back.</para>
<para>Exactly which <exceptionname>Exception</exceptionname> types mark
TR: Errors aren't thrown by application code, only checked or unchecked exceptions are. So the Errors part is just clarifying that
a transaction for rollback can be configured. Find below a snippet of
if the underlying application server infrastructure throws an Error the transaction will be rolled back--></para>
XML configuration that demonstrates how one would configure rollback for
a checked, application-specific <exceptionname>Exception</exceptionname>
<para>You can configure exactly which
type.</para>
<exceptionname>Exception</exceptionname> types mark a transaction for
rollback. The following XML snippet demonstrates how you configure
<para>Consider the use of AspectJ mode (see below) if you expect
<para>Consider the use of AspectJ mode (see below) if you expect
self-invocations to be wrapped with transactions as well. In this case,
self-invocations to be wrapped with transactions as well. <!--*see below* is not clear re AspectJmode. Provide clear x-ref to mode in table below, or to Using Transactional with AspectJ section. Also clarify reference to *as well*. As well as what?--><!--Below, *in this case* meaning in *what* case? Explain what table shows.-->In
there won't be a proxy in the first place; instead, the target class
this case, there will not be a proxy in the first place; instead, the
will be 'weaved' (i.e. its byte code will be modified) in order to turn
target class will be weaved (that is, its byte code will be modified) in
<interfacename>@Transactional</interfacename> into runtime behavior on
order to turn <interfacename>@Transactional</interfacename> into runtime
method, you want to see the following actions:<!--I changed this to a numbered list because language indicated that one thing happens after another.--></para>
<para>then the transactional advice executing,</para>
<para>Transactional advice executes.</para>
</listitem>
</listitem>
<listitem>
<listitem>
<para>then the method on the advised object executing</para>
<para>Method on the advised object executes.</para>
</listitem>
</listitem>
<listitem>
<listitem>
<para>then the transaction committing (we'll assume a sunny day
<para>Transaction commits.</para>
scenario here),</para>
</listitem>
</listitem>
<listitem>
<listitem>
<para>and then finally the profiling aspect reporting (somehow)
<para>Profiling aspect reports exact duration of the whole
exactly how long the whole transactional method invocation
transactional method invocation.</para>
took</para>
</listitem>
</listitem>
</itemizedlist>
</orderedlist>
<note>
<note>
<para>This chapter is not concerned with explaining AOP in any great
<para>This chapter is not concerned with explaining AOP in any great
detail (except as it applies to transactions). Please see the chapter
detail (except as it applies to transactions). See <xref
entitled <xreflinkend="aop"/> for detailed coverage of the various
linkend="aop"/> for detailed coverage of the following AOP
bits and pieces of the following AOP configuration (and AOP in
configuration and AOP in general.</para>
general).</para>
</note>
</note>
<para>Here is the code for a simple profiling aspect. The ordering of
<para>Here is the code for a simple profiling aspect discussed above.
advice is controlled via the <interfacename>Ordered</interfacename>
<!--If you mean this code produces actions above, say that. TR: added 'discussed above'-->The
interface. For full details on advice ordering, see <xref
ordering of advice is controlled through the
<interfacename>Ordered</interfacename> interface. For full details on
advice ordering, see <xref
linkend="aop-ataspectj-advice-ordering"/>.</para>
linkend="aop-ataspectj-advice-ordering"/>.</para>
<programlistinglanguage="java">package x.y;
<programlistinglanguage="java">package x.y;
...
@@ -1909,15 +1949,14 @@ public class SimpleProfiler implements Ordered {
...
@@ -1909,15 +1949,14 @@ public class SimpleProfiler implements Ordered {
</beans></programlisting>
</beans></programlisting>
<para>The result of the above configuration will be a
<para>The result of the above configuration is a
<literal>'fooService'</literal> bean that has profiling and
<literal>fooService</literal> bean that has profiling and transactional
transactional aspects applied to it <emphasis>in that order</emphasis>.
aspects applied to it <emphasis>in the desired order</emphasis>. <!--By *that order,* indicate whether you mean the numbered process or the above example? Or are they the same?
The configuration of any number of additional aspects is effected in a
TR: changed to 'desired'; seems clear that the desired order is profiling first followed by transactional aspect-->You
similar fashion.</para>
configure any number of additional aspects in similar fashion.</para>
<para>Finally, find below some example configuration for effecting the
<para>The following example effects the same setup as above, but uses
same setup as above, but using the purely XML declarative