Move section on event wiring from misc to objects.xml
Fix tx-namespace usage in xml
This commit is contained in:
@@ -1,182 +1,154 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<chapter xml:id="misc" xmlns="http://docbook.org/ns/docbook" version="5">
|
||||
<title>Spring.NET miscellanea</title>
|
||||
<sect1>
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
This chapter contains miscellanea information on features, goodies, caveats
|
||||
that does not belong to any paricular area.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1>
|
||||
<title>PathMatcher</title>
|
||||
<para>
|
||||
<emphasis>Note, Spring.Util.PathMatcher is
|
||||
currently only available in CVS, not the RC3 release. If you want to use these feature
|
||||
please get the code from CVS
|
||||
<ulink url="http://opensource.atlassian.com/confluence/spring/display/NET/Project+Structure">(instructions)</ulink>
|
||||
or from the download section of the
|
||||
Spring.NET website that contains an .zip with the full CVS tree.
|
||||
</emphasis>
|
||||
</para>
|
||||
<para>
|
||||
<literal>Spring.Util.PathMatcher</literal> provides <literal>Ant/NAnt</literal>-like path name matching
|
||||
features.
|
||||
</para>
|
||||
<para>To do the match, you use the method:
|
||||
<programlisting language="csharp">static bool Match(string pattern, string path)</programlisting>
|
||||
</para>
|
||||
<para>If you want to decide if case is important or not use the method:
|
||||
<programlisting language="csharp">static bool Match(string pattern, string path, bool ignoreCase)</programlisting>
|
||||
</para>
|
||||
<sect2>
|
||||
<title>General rules</title>
|
||||
<para>
|
||||
To build your pattern, you use the <literal>*</literal>, <literal>?</literal>
|
||||
and <literal>**</literal> building blocks:
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para><literal>*</literal>: matches any number of non slash
|
||||
characters;
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><literal>?</literal>: matches exactly 1 (one) non slash/dot
|
||||
character;
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><literal>**</literal>: matches any subdirectory, without
|
||||
taking care of the depth;
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Matching filenames</title>
|
||||
<para>
|
||||
A file name can be matched using the following
|
||||
notation:
|
||||
<programlisting>foo?bar.*</programlisting>
|
||||
matches:
|
||||
<programlisting>fooAbar.txt
|
||||
foo1bar.txt
|
||||
foo_bar.txt
|
||||
foo-bar.txt</programlisting>
|
||||
does not match:
|
||||
<programlisting>foo.bar.txt
|
||||
foo/bar.txt
|
||||
foo\bar.txt</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
The classical all files pattern:
|
||||
<programlisting>*.*</programlisting>
|
||||
matches:
|
||||
<programlisting>foo.db
|
||||
.db
|
||||
foo
|
||||
foo.bar.db
|
||||
foo.db.db
|
||||
db.db.db</programlisting>
|
||||
does not match:
|
||||
<programlisting>c:/
|
||||
c:/foo.db
|
||||
c:/foo
|
||||
c:/.db
|
||||
c:/foo.foo.db
|
||||
//server/foo</programlisting>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Matching subdirectories</title>
|
||||
<para>
|
||||
A directory name can be matched at any depth level using the following
|
||||
notation:
|
||||
<programlisting>**/db/**</programlisting>
|
||||
That pattern matches the following paths:
|
||||
<programlisting>/db
|
||||
//server/db
|
||||
c:/db
|
||||
c:/spring/app/db/foo.db
|
||||
//Program Files/App/spaced dir/db/foo.db
|
||||
/home/spring/spaced dir/db/v1/foo.db</programlisting>
|
||||
but does not match these:
|
||||
<programlisting>c:/spring/app/db-v1/foo.db
|
||||
/home/spring/spaced dir/db-v1/foo.db</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
You can compose subdirectories to match like this:
|
||||
<programlisting>**/bin/**/tmp/**</programlisting>
|
||||
That pattern matches the following paths:
|
||||
<programlisting>c:/spring/foo/bin/bar/tmp/a
|
||||
c:/spring/foo/bin/tmp/a/b.c</programlisting>
|
||||
but does not match these:
|
||||
<programlisting>c:/spring/foo/bin/bar/temp/a
|
||||
c:/tmp/foo/bin/bar/a/b.c</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
You can use more advanced patterns:
|
||||
<programlisting>**/.spring-assemblies*/**</programlisting>
|
||||
matches:
|
||||
<programlisting>c:/.spring-assemblies
|
||||
c:/.spring-assembliesabcd73xs
|
||||
c:/app/.spring-assembliesabcd73xs
|
||||
c:/app/.spring-assembliesabcd73xs/foo.dll
|
||||
//server/app/.spring-assembliesabcd73xs</programlisting>
|
||||
does not match:
|
||||
<programlisting>c:/app/.spring-assemblie</programlisting>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Case does matter, slashes don't</title>
|
||||
<para>
|
||||
.NET is expected to be a cross-platform development ... platform. So,
|
||||
<literal>PathMatcher</literal> will match taking care of the case of the pattern
|
||||
and the case of the path. For example:
|
||||
<programlisting>**/db/**/*.DB</programlisting>
|
||||
matches:
|
||||
<programlisting>c:/spring/service/deploy/app/db/foo.DB</programlisting>
|
||||
but does not match:
|
||||
<programlisting>c:/spring/service/deploy/app/DB/foo.DB
|
||||
c:spring/service/deploy/app/spaced dir/DB/foo.DB
|
||||
//server/share/service/deploy/app/DB/backup/foo.db</programlisting>
|
||||
</para>
|
||||
<para>If you do not matter about case, you should explicitly tell the
|
||||
<literal>Pathmatcher</literal>.</para>
|
||||
<para>
|
||||
Back and forward slashes, in the very same cross-platform spirit, are
|
||||
not important:
|
||||
<programlisting>spring/foo.bar</programlisting>
|
||||
matches all the following paths:
|
||||
<programlisting>c:\spring\foo.bar
|
||||
c:/spring\foo.bar
|
||||
c:/spring/foo.bar
|
||||
/spring/foo.bar
|
||||
\spring\foo.bar</programlisting>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<chapter version="5" xml:id="misc" xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:ns6="http://www.w3.org/1999/xlink"
|
||||
xmlns:ns5="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ns4="http://www.w3.org/2000/svg"
|
||||
xmlns:ns3="http://www.w3.org/1998/Math/MathML"
|
||||
xmlns:ns="http://docbook.org/ns/docbook">
|
||||
<title>Spring.NET miscellanea</title>
|
||||
|
||||
<section xml:id="spring-net-miscellanea">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>This chapter contains miscellanea information on features, goodies,
|
||||
caveats that does not belong to any paricular area.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="pathmatcher">
|
||||
<title>PathMatcher</title>
|
||||
|
||||
<para><emphasis>Note, Spring.Util.PathMatcher is currently only available
|
||||
in CVS, not the RC3 release. If you want to use these feature please get
|
||||
the code from CVS <ulink
|
||||
url="http://opensource.atlassian.com/confluence/spring/display/NET/Project+Structure">(instructions)</ulink>
|
||||
or from the download section of the Spring.NET website that contains an
|
||||
.zip with the full CVS tree. </emphasis></para>
|
||||
|
||||
<para><literal>Spring.Util.PathMatcher</literal> provides
|
||||
<literal>Ant/NAnt</literal>-like path name matching features.</para>
|
||||
|
||||
<para>To do the match, you use the method: <programlisting
|
||||
language="csharp">static bool Match(string pattern, string path)</programlisting></para>
|
||||
|
||||
<para>If you want to decide if case is important or not use the method:
|
||||
<programlisting language="csharp">static bool Match(string pattern, string path, bool ignoreCase)</programlisting></para>
|
||||
|
||||
<section xml:id="pathmatcher-general-rules">
|
||||
<title>General rules</title>
|
||||
|
||||
<para>To build your pattern, you use the <literal>*</literal>,
|
||||
<literal>?</literal> and <literal>**</literal> building blocks:
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para><literal>*</literal>: matches any number of non slash
|
||||
characters;</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>?</literal>: matches exactly 1 (one) non slash/dot
|
||||
character;</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>**</literal>: matches any subdirectory, without
|
||||
taking care of the depth;</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
</section>
|
||||
|
||||
<section xml:id="pathmatcher-matching-filenames">
|
||||
<title>Matching filenames</title>
|
||||
|
||||
<para>A file name can be matched using the following notation:
|
||||
<programlisting>foo?bar.*</programlisting> matches: <programlisting>fooAbar.txt
|
||||
foo1bar.txt
|
||||
foo_bar.txt
|
||||
foo-bar.txt</programlisting> does not match: <programlisting>foo.bar.txt
|
||||
foo/bar.txt
|
||||
foo\bar.txt</programlisting></para>
|
||||
|
||||
<para>The classical all files pattern: <programlisting>*.*</programlisting>
|
||||
matches: <programlisting>foo.db
|
||||
.db
|
||||
foo
|
||||
foo.bar.db
|
||||
foo.db.db
|
||||
db.db.db</programlisting> does not match: <programlisting>c:/
|
||||
c:/foo.db
|
||||
c:/foo
|
||||
c:/.db
|
||||
c:/foo.foo.db
|
||||
//server/foo</programlisting></para>
|
||||
</section>
|
||||
|
||||
<section xml:id="pathmatcher-matching-subdirectories">
|
||||
<title>Matching subdirectories</title>
|
||||
|
||||
<para>A directory name can be matched at any depth level using the
|
||||
following notation: <programlisting>**/db/**</programlisting> That
|
||||
pattern matches the following paths: <programlisting>/db
|
||||
//server/db
|
||||
c:/db
|
||||
c:/spring/app/db/foo.db
|
||||
//Program Files/App/spaced dir/db/foo.db
|
||||
/home/spring/spaced dir/db/v1/foo.db</programlisting> but does not match
|
||||
these: <programlisting>c:/spring/app/db-v1/foo.db
|
||||
/home/spring/spaced dir/db-v1/foo.db</programlisting></para>
|
||||
|
||||
<para>You can compose subdirectories to match like this:
|
||||
<programlisting>**/bin/**/tmp/**</programlisting> That pattern matches
|
||||
the following paths: <programlisting>c:/spring/foo/bin/bar/tmp/a
|
||||
c:/spring/foo/bin/tmp/a/b.c</programlisting> but does not match these:
|
||||
<programlisting>c:/spring/foo/bin/bar/temp/a
|
||||
c:/tmp/foo/bin/bar/a/b.c</programlisting></para>
|
||||
|
||||
<para>You can use more advanced patterns: <programlisting>**/.spring-assemblies*/**</programlisting>
|
||||
matches: <programlisting>c:/.spring-assemblies
|
||||
c:/.spring-assembliesabcd73xs
|
||||
c:/app/.spring-assembliesabcd73xs
|
||||
c:/app/.spring-assembliesabcd73xs/foo.dll
|
||||
//server/app/.spring-assembliesabcd73xs</programlisting> does not match:
|
||||
<programlisting>c:/app/.spring-assemblie</programlisting></para>
|
||||
</section>
|
||||
|
||||
<section xml:id="pathmatcher-case-matters">
|
||||
<title>Case does matter, slashes don't</title>
|
||||
|
||||
<para>.NET is expected to be a cross-platform development ... platform.
|
||||
So, <literal>PathMatcher</literal> will match taking care of the case of
|
||||
the pattern and the case of the path. For example: <programlisting>**/db/**/*.DB</programlisting>
|
||||
matches: <programlisting>c:/spring/service/deploy/app/db/foo.DB</programlisting>
|
||||
but does not match: <programlisting>c:/spring/service/deploy/app/DB/foo.DB
|
||||
c:spring/service/deploy/app/spaced dir/DB/foo.DB
|
||||
//server/share/service/deploy/app/DB/backup/foo.db</programlisting></para>
|
||||
|
||||
<para>If you do not matter about case, you should explicitly tell the
|
||||
<literal>Pathmatcher</literal>.</para>
|
||||
|
||||
<para>Back and forward slashes, in the very same cross-platform spirit,
|
||||
are not important: <programlisting>spring/foo.bar</programlisting>
|
||||
matches all the following paths: <programlisting>c:\spring\foo.bar
|
||||
c:/spring\foo.bar
|
||||
c:/spring/foo.bar
|
||||
/spring/foo.bar
|
||||
\spring\foo.bar</programlisting></para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
@@ -2111,6 +2111,163 @@ public class MixedIocObject
|
||||
</sect3>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Declarative Event Listener Registration</title>
|
||||
|
||||
<para>In C# events are built right into the language thanks to the
|
||||
<literal>event</literal> keyword. Under the scenes, events are
|
||||
essentially a shorthand notation for delegates with some additional
|
||||
guidelines as to what the parameters to an event handler method should
|
||||
be (i.e. a sender <literal>System.Object</literal> and an
|
||||
<literal>System.EventArgs</literal> object).</para>
|
||||
|
||||
<para><programlisting language="csharp">public class EventSource
|
||||
public event EventHandler Click;</programlisting></para>
|
||||
|
||||
<para>In use, .NET events are combined with one or more event handler
|
||||
methods. Each handler method is programmatically added, or removed, from
|
||||
the event and corresponds to an object's method that should be invoked
|
||||
when a particular event occurs. When more than one handler method is
|
||||
added to an event, then each of the registered methods will be invoked
|
||||
in turn when an event occurs.</para>
|
||||
|
||||
<para><programlisting language="csharp">TestObject source = new TestObject();
|
||||
TestEventHandler eventListener1 = new TestEventHandler();
|
||||
TestEventHandler eventListener2 = new TestEventHandler();
|
||||
|
||||
source.Click += eventListener1.HandleEvent; // Adding the first event handler method to the event
|
||||
source.Click += eventListener2.HandleEvent; // Adding a second event handler method to the event
|
||||
|
||||
source.OnClick(); // First eventListener1.HandleEvent is invoked, then eventListener2.HandleEvent</programlisting></para>
|
||||
|
||||
<para>When OnClick() is invoked, the event is fired.</para>
|
||||
|
||||
<para><programlisting language="csharp">public void OnClick()
|
||||
{
|
||||
if (Click != null)
|
||||
{
|
||||
Click(this, EventArgs.Empty); // Fire the event off to the registered handler methods
|
||||
}
|
||||
}</programlisting></para>
|
||||
|
||||
<para>One of the not so nice things about using events is that, without
|
||||
employing late binding, you declare the objects that are registered with
|
||||
a particular event programmatically. Spring .NET offers a way to
|
||||
declaratively register your handler methods with particular events using
|
||||
the <literal><listener></literal> element inside your
|
||||
<literal><object></literal> elements.</para>
|
||||
|
||||
<sect3>
|
||||
<title>Declarative event handlers</title>
|
||||
|
||||
<para>Rather than having to specifically declare in your code that you
|
||||
are adding a method to be invoked on an event, using the
|
||||
<literal><listener></literal> element you can register a plain
|
||||
object's methods with the corresponding event declaratively in your
|
||||
application configuration.</para>
|
||||
|
||||
<para>Using the <literal>listener</literal> element you can:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<link linkend="objects-simple-event-configuration">Configure a
|
||||
method to be invoked when an event is fired.</link>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<link linkend="objects-handler-reg-ex-configuration">Register a
|
||||
collection of handler methods based on a regular
|
||||
expression.</link>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<link linkend="objects-event-name-reg-ex-configuration">Register
|
||||
a handler method against an event name that contains a regular
|
||||
expression.</link>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
</sect3>
|
||||
|
||||
<sect3 xml:id="objects-simple-event-configuration">
|
||||
<title>Configuring a method to be invoked when an event is
|
||||
fired</title>
|
||||
|
||||
<para>The same event registration in the example above can be achieved
|
||||
using configuration using the <literal><listener></literal>
|
||||
element.</para>
|
||||
|
||||
<para><programlisting language="myxml"><object id="eventListener1" type="SpringdotNETEventsExample.TestEventHandler, SpringdotNETEventsExample">
|
||||
<!-- wired up to an event exposed on an instance -->
|
||||
<listener event="Click" method="HandleEvent">
|
||||
<ref object="source"/>
|
||||
</listener>
|
||||
</object>
|
||||
|
||||
<object id="eventListener2" type="SpringdotNETEventsExample.TestEventHandler, SpringdotNETEventsExample">
|
||||
<!-- wired up to an event exposed on an instance -->
|
||||
<listener event="Click" method="HandleEvent">
|
||||
<ref object="source"/>
|
||||
</listener>
|
||||
</object></programlisting></para>
|
||||
|
||||
<para>In this case the two different objects will have their
|
||||
<literal>HandleEvent</literal> method invoked, as indicated explicitly
|
||||
using the <literal>method</literal> attribute, when a
|
||||
<literal>Click</literal> event, as specified by the
|
||||
<literal>event</literal> attribute, is triggered on the object
|
||||
referred to by the <literal>ref</literal> element.</para>
|
||||
</sect3>
|
||||
|
||||
<sect3 xml:id="objects-handler-reg-ex-configuration">
|
||||
<title>Registering a collection of handler methods based on a regular
|
||||
expression</title>
|
||||
|
||||
<para>Regular expressions can be employed to wire up more than one
|
||||
handler method to an object that contains one or more events.</para>
|
||||
|
||||
<para><programlisting language="myxml"><object id="eventListener" type="SpringdotNETEventsExample.TestEventHandler, SpringdotNETEventsExample">
|
||||
<listener method="Handle.+">
|
||||
<ref object="source"/>
|
||||
</listener>
|
||||
</object></programlisting></para>
|
||||
|
||||
<para>Here all the <literal>eventListener</literal>'s handler methods
|
||||
that begin with 'Handle', and that have the corresponding two
|
||||
parameters of a <literal>System.Object</literal> and a
|
||||
<literal>System.EventArgs</literal>, will be registered against all
|
||||
events exposed by the <literal>source</literal> object.</para>
|
||||
|
||||
<para>You can also use the name of the event in regular expression to
|
||||
filter your handler methods based on the type of event
|
||||
triggered.</para>
|
||||
|
||||
<para><programlisting language="myxml"><object id="eventListener" type="SpringdotNETEventsExample.TestEventHandler, SpringdotNETEventsExample">
|
||||
<!-- For the Click event, the HandleClick handler method will be invoked. -->
|
||||
<listener method="Handle${event}">
|
||||
<ref object="source"/>
|
||||
</listener>
|
||||
</object></programlisting></para>
|
||||
</sect3>
|
||||
|
||||
<sect3 xml:id="objects-event-name-reg-ex-configuration">
|
||||
<title>Registering a handler method against an event name that
|
||||
contains a regular expression</title>
|
||||
|
||||
<para>Finally, you can register an object's handler methods against a
|
||||
selection of events, filtering based on their name using a regular
|
||||
expression.</para>
|
||||
|
||||
<para><programlisting language="myxml"><object id="eventListener" type="SpringdotNETEventsExample.TestEventHandler, SpringdotNETEventsExample">
|
||||
<listener method="HandleEvent" event="Cl.+">
|
||||
<ref object="source"/>
|
||||
</listener>
|
||||
</object></programlisting></para>
|
||||
|
||||
<para>In this example the <literal>eventListener</literal>'s
|
||||
<literal>HandleEvent</literal> handler method will be invoked for any
|
||||
event that begins with 'Cl'.</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
|
||||
<sect2 xml:id="objects-factory-dependson">
|
||||
<title>Using <literal>depends-on</literal></title>
|
||||
|
||||
|
||||
@@ -16,7 +16,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<chapter xml:id="transaction" xmlns="http://docbook.org/ns/docbook" version="5">
|
||||
<chapter version="5" xml:id="transaction"
|
||||
xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:ns6="http://www.w3.org/1999/xlink"
|
||||
xmlns:ns5="http://www.w3.org/2000/svg"
|
||||
xmlns:ns4="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ns3="http://www.w3.org/1998/Math/MathML"
|
||||
xmlns:ns="http://docbook.org/ns/docbook">
|
||||
<title>Transaction management</title>
|
||||
|
||||
<sect1 xml:id="tx-introduction">
|
||||
@@ -40,7 +46,8 @@
|
||||
|
||||
<listitem>
|
||||
<para>Provides a simple API for <link
|
||||
linkend="transaction-programmatic">programmatic</link> transaction management</para>
|
||||
linkend="transaction-programmatic">programmatic</link> transaction
|
||||
management</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
@@ -76,9 +83,10 @@
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The fourth section, entitled <link linkend="transaction-programmatic">Programmatic
|
||||
transaction management</link>, covers support for programmatic
|
||||
transaction management.</para>
|
||||
<para>The fourth section, entitled <link
|
||||
linkend="transaction-programmatic">Programmatic transaction
|
||||
management</link>, covers support for programmatic transaction
|
||||
management.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
@@ -215,16 +223,16 @@
|
||||
|
||||
<para>This is primarily a 'SPI' (Service Provider Interface), although it
|
||||
can be used Programatically. Note that in keeping with the Spring
|
||||
Framework's philosophy, <literal>IPlatformTransactionManager</literal>
|
||||
is an interface, and can thus be easily mocked or stubbed as necessary.
|
||||
<literal>IPlatformTransactionManager</literal> implementations
|
||||
are defined like any other object in the IoC container. The following
|
||||
implementations are provided</para>
|
||||
Framework's philosophy, <literal>IPlatformTransactionManager</literal> is
|
||||
an interface, and can thus be easily mocked or stubbed as necessary.
|
||||
<literal>IPlatformTransactionManager</literal> implementations are defined
|
||||
like any other object in the IoC container. The following implementations
|
||||
are provided</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>AdoPlatformTransactionManager</literal> - local
|
||||
ADO.NET based transactions</para>
|
||||
<para><literal>AdoPlatformTransactionManager</literal> - local ADO.NET
|
||||
based transactions</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
@@ -238,8 +246,8 @@
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>HibernatePlatformTransactionManager</literal> -
|
||||
local transaction manager for use with NHibernate or mixed
|
||||
<para><literal>HibernatePlatformTransactionManager</literal> - local
|
||||
transaction manager for use with NHibernate or mixed
|
||||
ADO.NET/NHibernate data access operations.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
@@ -261,11 +269,10 @@
|
||||
<para>The <literal>GetTransaction(..)</literal> method returns a
|
||||
<literal>ITransactionStatus</literal> object, depending on a
|
||||
<literal>ITransactionDefinition</literal> parameters. The returned
|
||||
<literal>ITransactionStatus</literal> might represent a new or
|
||||
existing transaction (if there was a matching transaction in the current
|
||||
call stack - with the implication being that a
|
||||
<literal>ITransactionStatus</literal> is associated with a logical
|
||||
thread of execution.</para>
|
||||
<literal>ITransactionStatus</literal> might represent a new or existing
|
||||
transaction (if there was a matching transaction in the current call stack
|
||||
- with the implication being that a <literal>ITransactionStatus</literal>
|
||||
is associated with a logical thread of execution.</para>
|
||||
|
||||
<para>The <literal>ITransactionDefinition</literal> interface
|
||||
specified</para>
|
||||
@@ -305,28 +312,25 @@
|
||||
concepts is essential to using the Spring Framework or indeed any other
|
||||
transaction management solution.</para>
|
||||
|
||||
<para>The <literal>ITransactionStatus</literal> interface
|
||||
provides a simple way for transactional code to control transaction
|
||||
execution and query transaction status.</para>
|
||||
<para>The <literal>ITransactionStatus</literal> interface provides a
|
||||
simple way for transactional code to control transaction execution and
|
||||
query transaction status.</para>
|
||||
|
||||
<para>Regardless of whether you opt for declarative or programmatic
|
||||
transaction management in Spring, defining the correct
|
||||
<literal>IPlatformTransactionManager</literal> implementation
|
||||
is absolutely essential. In good Spring fashion, this important definition
|
||||
<literal>IPlatformTransactionManager</literal> implementation is
|
||||
absolutely essential. In good Spring fashion, this important definition
|
||||
typically is made using via Dependency Injection.</para>
|
||||
|
||||
<para><literal>IPlatformTransactionManager</literal>
|
||||
implementations normally require knowledge of the environment in which
|
||||
they work, ADO.NET, NHibernate, etc. The following example shows how a
|
||||
standard ADO.NET based
|
||||
<literal>IPlatformTransactionManager</literal> can be
|
||||
defined.</para>
|
||||
<para><literal>IPlatformTransactionManager</literal> implementations
|
||||
normally require knowledge of the environment in which they work, ADO.NET,
|
||||
NHibernate, etc. The following example shows how a standard ADO.NET based
|
||||
<literal>IPlatformTransactionManager</literal> can be defined.</para>
|
||||
|
||||
<para>We must define a Spring <literal>IDbProvider</literal>
|
||||
and then use Spring's
|
||||
<literal>AdoPlatformTransactionManager</literal>, giving it a
|
||||
reference to the <literal>IDbProvider</literal>. For more information
|
||||
on the <literal>IDbProvider</literal> abstraction refer to the next
|
||||
<para>We must define a Spring <literal>IDbProvider</literal> and then use
|
||||
Spring's <literal>AdoPlatformTransactionManager</literal>, giving it a
|
||||
reference to the <literal>IDbProvider</literal>. For more information on
|
||||
the <literal>IDbProvider</literal> abstraction refer to the next
|
||||
chapter.</para>
|
||||
|
||||
<programlisting language="myxml"><objects xmlns='http://www.springframework.net'
|
||||
@@ -463,9 +467,9 @@
|
||||
specify which exceptions should cause automatic roll back. We specify this
|
||||
declaratively, in configuration, not in code. So, while we can still set
|
||||
<literal>RollbackOnly</literal> on the
|
||||
<literal>ITransactionStatus</literal> object to roll the
|
||||
current transaction back Programatically, most often we can specify a rule
|
||||
that MyApplicationException must always result in rollback. This has the
|
||||
<literal>ITransactionStatus</literal> object to roll the current
|
||||
transaction back Programatically, most often we can specify a rule that
|
||||
MyApplicationException must always result in rollback. This has the
|
||||
significant advantage that business objects don't need to depend on the
|
||||
transaction infrastructure. For example, they typically don't need to
|
||||
import any Spring APIs, transaction or other. If you would like to
|
||||
@@ -481,8 +485,8 @@
|
||||
</note>
|
||||
|
||||
<sect2 xml:id="tx-understandingimpl">
|
||||
<title>Understanding
|
||||
Spring's declarative transaction implementation</title>
|
||||
<title>Understanding Spring's declarative transaction
|
||||
implementation</title>
|
||||
|
||||
<para>The aim of this section is to dispel the mystique that is
|
||||
sometimes associated with the use of declarative transactions. It is all
|
||||
@@ -522,7 +526,7 @@
|
||||
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="images/tx.png" />
|
||||
<imagedata fileref="images/tx.png"></imagedata>
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
|
||||
@@ -534,9 +538,9 @@
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>ProxyFactoryObject</literal>. The common
|
||||
properties to set are the reference to the object to proxy (the
|
||||
target object) and a reference to the transaction advice. See <xref
|
||||
<para><literal>ProxyFactoryObject</literal>. The common properties
|
||||
to set are the reference to the object to proxy (the target object)
|
||||
and a reference to the transaction advice. See <xref
|
||||
linkend="aop-proxyfactoryobject" /> for more details.</para>
|
||||
</listitem>
|
||||
|
||||
@@ -555,10 +559,10 @@
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>DefaultAdvisorAutoProxyCreator</literal>
|
||||
which specifies one or more "advisors" i.e an object
|
||||
representing an aspect, including both an advice and a pointcut
|
||||
targeting it to specific joinpoints. See <xref
|
||||
<para><literal>DefaultAdvisorAutoProxyCreator</literal> which
|
||||
specifies one or more "advisors" i.e an object representing an
|
||||
aspect, including both an advice and a pointcut targeting it to
|
||||
specific joinpoints. See <xref
|
||||
linkend="aop-advisorautoproxy" /></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
@@ -567,8 +571,8 @@
|
||||
|
||||
<para>There is also a convenience subclass of
|
||||
<literal>ProxyFactoryObject</literal>, namely
|
||||
<literal>TransactionProxyFactoryObject</literal>, that sets some
|
||||
common default values for the specific case of applying transactional
|
||||
<literal>TransactionProxyFactoryObject</literal>, that sets some common
|
||||
default values for the specific case of applying transactional
|
||||
advice.</para>
|
||||
|
||||
<para>The <literal>DefaultAdvisorAutoProxyCreator</literal> is very
|
||||
@@ -610,11 +614,11 @@
|
||||
<para>Consider the following interface. The intent is to convey the
|
||||
concepts to you so you can concentrate on the transaction usage and not
|
||||
have to worry about domain specific details. The
|
||||
<literal>ITestObjectManager</literal> is a poor-mans
|
||||
business service layer - the implementation of which will make two DAO
|
||||
calls. Clearly this example is overly simplistic from the service layer
|
||||
perspective as there isn't any business logic at all!. The 'service'
|
||||
interface is shown below.</para>
|
||||
<literal>ITestObjectManager</literal> is a poor-mans business service
|
||||
layer - the implementation of which will make two DAO calls. Clearly
|
||||
this example is overly simplistic from the service layer perspective as
|
||||
there isn't any business logic at all!. The 'service' interface is shown
|
||||
below.</para>
|
||||
|
||||
<programlisting language="csharp">public interface ITestObjectManager
|
||||
{
|
||||
@@ -623,8 +627,8 @@
|
||||
void DeleteTwoTestObjects(string name1, string name2);
|
||||
}</programlisting>
|
||||
|
||||
<para>The implementation of
|
||||
<literal>ITestObjectManager</literal> is shown below</para>
|
||||
<para>The implementation of <literal>ITestObjectManager</literal> is
|
||||
shown below</para>
|
||||
|
||||
<programlisting language="csharp">public class TestObjectManager : ITestObjectManager
|
||||
{
|
||||
@@ -669,8 +673,8 @@
|
||||
}</programlisting>
|
||||
|
||||
<para>The Create and Delete method implementation is shown below. Note
|
||||
that this uses the <literal>AdoTemplate</literal> class discussed in
|
||||
the following chapter. Refer to <xref linkend="resource-sync" /> for
|
||||
that this uses the <literal>AdoTemplate</literal> class discussed in the
|
||||
following chapter. Refer to <xref linkend="resource-sync" /> for
|
||||
information on the interaction between Spring's high level persistence
|
||||
integration APIs and transaction management features.</para>
|
||||
|
||||
@@ -691,15 +695,14 @@
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>The <literal>TestObjectManager</literal> is configured with
|
||||
the DAO objects by standard dependency injection techniques. The client
|
||||
<para>The <literal>TestObjectManager</literal> is configured with the
|
||||
DAO objects by standard dependency injection techniques. The client
|
||||
code, which in this case directly asks the Spring IoC container for an
|
||||
instance of <literal>ITestObjectManager</literal>, will
|
||||
receive a transaction proxy with transaction options based on the
|
||||
attribute metadata. Note that typically the
|
||||
<literal>ITestObjectManager</literal> would be set on yet
|
||||
another higher level object via dependency injection, for example a web
|
||||
service.</para>
|
||||
instance of <literal>ITestObjectManager</literal>, will receive a
|
||||
transaction proxy with transaction options based on the attribute
|
||||
metadata. Note that typically the <literal>ITestObjectManager</literal>
|
||||
would be set on yet another higher level object via dependency
|
||||
injection, for example a web service.</para>
|
||||
|
||||
<para>The client calling code is shown below</para>
|
||||
|
||||
@@ -807,26 +810,26 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>TransactionInterceptor</literal> is the AOP
|
||||
advice responsible for performing transaction management
|
||||
<para><literal>TransactionInterceptor</literal> is the AOP advice
|
||||
responsible for performing transaction management
|
||||
functionality.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>TransactionAttributeSourceAdvisor</literal> is an
|
||||
AOP Advisor that holds the TransactionInterceptor, which is the
|
||||
advice, and a pointcut (where to apply the advice), in the form of a
|
||||
<para><literal>TransactionAttributeSourceAdvisor</literal> is an AOP
|
||||
Advisor that holds the TransactionInterceptor, which is the advice,
|
||||
and a pointcut (where to apply the advice), in the form of a
|
||||
TransactionAttributeSource.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>AttributesTransactionAttributeSource</literal> is
|
||||
an implementation of the
|
||||
<literal>ITransactionAttributeSource</literal> interface that
|
||||
defines where to get the transaction metadata defining the
|
||||
transaction semantics (isolation level, propagation behavior, etc)
|
||||
that should be applied to specific methods of specific classes. The
|
||||
transaction metadata is specified via implementations of the
|
||||
<para><literal>AttributesTransactionAttributeSource</literal> is an
|
||||
implementation of the <literal>ITransactionAttributeSource</literal>
|
||||
interface that defines where to get the transaction metadata
|
||||
defining the transaction semantics (isolation level, propagation
|
||||
behavior, etc) that should be applied to specific methods of
|
||||
specific classes. The transaction metadata is specified via
|
||||
implementations of the
|
||||
<literal>ITransactionAttributeSource</literal> interface. This
|
||||
example shows the use of the implementation
|
||||
<literal>Spring.Transaction.Interceptor.AttributesTransactionAttributeSource</literal>
|
||||
@@ -848,8 +851,8 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>AttributesTransactionAttributeSource</literal>
|
||||
: Use a standard. .NET attributes to specify the transactional
|
||||
<para><literal>AttributesTransactionAttributeSource</literal> :
|
||||
Use a standard. .NET attributes to specify the transactional
|
||||
information. See <literal>TransactionAttribute</literal> class
|
||||
for more information.</para>
|
||||
</listitem>
|
||||
@@ -877,8 +880,8 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>MethodMapTransactionAttributeSource</literal>
|
||||
: Similar to NameMatchTransactionAttributeSource but specifies
|
||||
<para><literal>MethodMapTransactionAttributeSource</literal> :
|
||||
Similar to NameMatchTransactionAttributeSource but specifies
|
||||
that only fully qualified method names (i.e. type.method,
|
||||
assembly) and wildcards can be used at the start or end of the
|
||||
method name for matching multiple methods.</para>
|
||||
@@ -887,8 +890,8 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>DefaultAdvisorAutoProxyCreator</literal>: looks
|
||||
for Advisors in the context, and automatically creates proxy objects
|
||||
<para><literal>DefaultAdvisorAutoProxyCreator</literal>: looks for
|
||||
Advisors in the context, and automatically creates proxy objects
|
||||
which are the transactional wrappers</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
@@ -944,7 +947,7 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
xmlns:db="http://www.springframework.net/database"
|
||||
xsi:schemaLocation="http://www.springframework.net http://www.springframework.net/schema/objects/spring-objects.xsd
|
||||
http://www.springframework.net/schema/tx http://www.springframework.net/schema/tx/spring-tx-1.1.xsd"
|
||||
http://www.springframework.net/schema/tx http://www.springframework.net/schema/tx/spring-database.xsd">
|
||||
http://www.springframework.net/schema/db http://www.springframework.net/schema/db/spring-database.xsd">
|
||||
|
||||
<db:provider id="DbProvider"
|
||||
provider="SqlServer-1.1"
|
||||
@@ -980,13 +983,12 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
<para>You can actually omit the
|
||||
<literal>'transaction-manager'</literal> attribute in the
|
||||
<literal><tx:attribute-driven/></literal> tag if the object
|
||||
name of the
|
||||
<literal>IPlatformTransactionManager</literal> that you
|
||||
name of the <literal>IPlatformTransactionManager</literal> that you
|
||||
want to wire in has the name
|
||||
<literal>'transactionManager'</literal>. If the
|
||||
<literal>PlatformTransactionManager</literal> object
|
||||
that you want to dependency inject has any other name, then you have
|
||||
to be explicit and use the <literal>'transaction-manager'</literal>
|
||||
<literal>PlatformTransactionManager</literal> object that you want
|
||||
to dependency inject has any other name, then you have to be
|
||||
explicit and use the <literal>'transaction-manager'</literal>
|
||||
attribute as in the example above.</para>
|
||||
</tip>The various optional elements of the
|
||||
<tx:attribute-driven/> tag are summarised in the following
|
||||
@@ -1011,57 +1013,68 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><literal>transaction-manager</literal></entry>
|
||||
<entry>
|
||||
<literal>transaction-manager</literal>
|
||||
</entry>
|
||||
|
||||
<entry>No</entry>
|
||||
|
||||
<entry>transactionManager</entry>
|
||||
|
||||
<entry><para>The name of transaction manager to use. Only
|
||||
required if the name of the transaction manager is not
|
||||
<literal>transactionManager</literal>, as in the example
|
||||
above.</para></entry>
|
||||
<entry>
|
||||
<para>The name of transaction manager to use. Only required
|
||||
if the name of the transaction manager is not
|
||||
<literal>transactionManager</literal>, as in the example
|
||||
above.</para>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>proxy-target-type</literal></entry>
|
||||
<entry>
|
||||
<literal>proxy-target-type</literal>
|
||||
</entry>
|
||||
|
||||
<entry>No</entry>
|
||||
|
||||
<entry></entry>
|
||||
<entry />
|
||||
|
||||
<entry><para>Controls what type of transactional proxies are
|
||||
created for classes annotated with the
|
||||
<literal>[Transaction]</literal> attribute. If
|
||||
"<literal>proxy-target-type</literal>" attribute is set to
|
||||
"<literal>true</literal>", then class-based proxies will be
|
||||
created (proxy inherits from target class, however calls are
|
||||
still delegated to target object via composition. This allows
|
||||
for casting to base class. If
|
||||
"<literal>proxy-target-type</literal>" is
|
||||
"<literal>false</literal>" or if the attribute is omitted,
|
||||
then a pure composition based proxy is created and you can
|
||||
only cast the proxy to implemented interfaces. (See the
|
||||
section entitled <xref linkend="aop-proxy-mechanism" /> for a
|
||||
detailed examination of the different proxy
|
||||
types.)</para></entry>
|
||||
<entry>
|
||||
<para>Controls what type of transactional proxies are
|
||||
created for classes annotated with the
|
||||
<literal>[Transaction]</literal> attribute. If
|
||||
"<literal>proxy-target-type</literal>" attribute is set to
|
||||
"<literal>true</literal>", then class-based proxies will be
|
||||
created (proxy inherits from target class, however calls are
|
||||
still delegated to target object via composition. This
|
||||
allows for casting to base class. If
|
||||
"<literal>proxy-target-type</literal>" is
|
||||
"<literal>false</literal>" or if the attribute is omitted,
|
||||
then a pure composition based proxy is created and you can
|
||||
only cast the proxy to implemented interfaces. (See the
|
||||
section entitled <xref linkend="aop-proxy-mechanism" /> for
|
||||
a detailed examination of the different proxy types.)</para>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>order</literal></entry>
|
||||
<entry>
|
||||
<literal>order</literal>
|
||||
</entry>
|
||||
|
||||
<entry>No</entry>
|
||||
|
||||
<entry></entry>
|
||||
<entry />
|
||||
|
||||
<entry><para>Defines the order of the transaction advice that
|
||||
will be applied to objects annotated with
|
||||
<code>[Transaction]</code>. More on the rules related to
|
||||
ordering of AOP advice can be found in the AOP chapter (see
|
||||
section <xref lang="" linkend="aop-advice-ordering" />). Note
|
||||
that not specifying any ordering will leave the decision as to
|
||||
what order advice is run in to the AOP
|
||||
subsystem.</para></entry>
|
||||
<entry>
|
||||
<para>Defines the order of the transaction advice that will
|
||||
be applied to objects annotated with
|
||||
<code>[Transaction]</code>. More on the rules related to
|
||||
ordering of AOP advice can be found in the AOP chapter (see
|
||||
section <xref lang="" linkend="aop-advice-ordering" />).
|
||||
Note that not specifying any ordering will leave the
|
||||
decision as to what order advice is run in to the AOP
|
||||
subsystem.</para>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
@@ -1214,23 +1227,29 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><literal>name</literal></entry>
|
||||
<entry>
|
||||
<literal>name</literal>
|
||||
</entry>
|
||||
|
||||
<entry>Yes</entry>
|
||||
|
||||
<entry></entry>
|
||||
<entry />
|
||||
|
||||
<entry><para>The method name(s) with which the transaction
|
||||
attributes are to be associated. The wildcard (*) character
|
||||
can be used to associate the same transaction attribute
|
||||
settings with a number of methods; for example,
|
||||
<literal>'Get*'</literal>,
|
||||
<literal>'Handle*'</literal>,<literal> 'On*Event'</literal>,
|
||||
and so forth.</para></entry>
|
||||
<entry>
|
||||
<para>The method name(s) with which the transaction
|
||||
attributes are to be associated. The wildcard (*) character
|
||||
can be used to associate the same transaction attribute
|
||||
settings with a number of methods; for example,
|
||||
<literal>'Get*'</literal>,
|
||||
<literal>'Handle*'</literal>,<literal> 'On*Event'</literal>,
|
||||
and so forth.</para>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>propagation</literal></entry>
|
||||
<entry>
|
||||
<literal>propagation</literal>
|
||||
</entry>
|
||||
|
||||
<entry>No</entry>
|
||||
|
||||
@@ -1240,7 +1259,9 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>isolation</literal></entry>
|
||||
<entry>
|
||||
<literal>isolation</literal>
|
||||
</entry>
|
||||
|
||||
<entry>No</entry>
|
||||
|
||||
@@ -1250,7 +1271,9 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>timeout</literal></entry>
|
||||
<entry>
|
||||
<literal>timeout</literal>
|
||||
</entry>
|
||||
|
||||
<entry>No</entry>
|
||||
|
||||
@@ -1260,7 +1283,9 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>read-only</literal></entry>
|
||||
<entry>
|
||||
<literal>read-only</literal>
|
||||
</entry>
|
||||
|
||||
<entry>No</entry>
|
||||
|
||||
@@ -1270,7 +1295,9 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>EnterpriseServicesInteropOption</literal></entry>
|
||||
<entry>
|
||||
<literal>EnterpriseServicesInteropOption</literal>
|
||||
</entry>
|
||||
|
||||
<entry>No</entry>
|
||||
|
||||
@@ -1281,28 +1308,36 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>rollback-for</literal></entry>
|
||||
<entry>
|
||||
<literal>rollback-for</literal>
|
||||
</entry>
|
||||
|
||||
<entry>No</entry>
|
||||
|
||||
<entry></entry>
|
||||
<entry />
|
||||
|
||||
<entry><para>The <literal>Exception(s)</literal> that will
|
||||
trigger rollback; comma-delimited. For example,
|
||||
<literal>'MyProduct.MyBusinessException,ValidationException'</literal></para></entry>
|
||||
<entry>
|
||||
<para>The <literal>Exception(s)</literal> that will trigger
|
||||
rollback; comma-delimited. For example,
|
||||
<literal>'MyProduct.MyBusinessException,ValidationException'</literal></para>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>no-rollback-for</literal></entry>
|
||||
<entry>
|
||||
<literal>no-rollback-for</literal>
|
||||
</entry>
|
||||
|
||||
<entry>No</entry>
|
||||
|
||||
<entry></entry>
|
||||
<entry />
|
||||
|
||||
<entry><para>The <literal>Exception(s)</literal> that will
|
||||
<emphasis>not</emphasis> trigger rollback; comma-delimited.
|
||||
For example,
|
||||
<literal>'MyProduct.MyBusinessException,ValidationException'</literal></para></entry>
|
||||
<entry>
|
||||
<para>The <literal>Exception(s)</literal> that will
|
||||
<emphasis>not</emphasis> trigger rollback; comma-delimited.
|
||||
For example,
|
||||
<literal>'MyProduct.MyBusinessException,ValidationException'</literal></para>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
@@ -1365,14 +1400,17 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry align="center"><emphasis
|
||||
role="bold">Property</emphasis></entry>
|
||||
<entry align="center">
|
||||
<emphasis role="bold">Property</emphasis>
|
||||
</entry>
|
||||
|
||||
<entry align="center"><emphasis
|
||||
role="bold">Type</emphasis></entry>
|
||||
<entry align="center">
|
||||
<emphasis role="bold">Type</emphasis>
|
||||
</entry>
|
||||
|
||||
<entry align="center"><emphasis
|
||||
role="bold">Description</emphasis></entry>
|
||||
<entry align="center">
|
||||
<emphasis role="bold">Description</emphasis>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
@@ -1388,7 +1426,9 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
<row>
|
||||
<entry>Isolation</entry>
|
||||
|
||||
<entry><literal>System.Data.IsolationLevel</literal></entry>
|
||||
<entry>
|
||||
<literal>System.Data.IsolationLevel</literal>
|
||||
</entry>
|
||||
|
||||
<entry>optional isolation level</entry>
|
||||
</row>
|
||||
@@ -1496,9 +1536,8 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
<link linkend="tx-firstexample">first example</link>. The use of
|
||||
Spring's autoproxy functionality defines criteria to select a collection
|
||||
of objects to create a transactional AOP proxy. There are two AutoProxy
|
||||
classes that you can use,
|
||||
<literal>ObjectNameAutoProxyCreator</literal> and
|
||||
<literal>DefaultAdvisorAutoProxyCreator</literal>. If you are using
|
||||
classes that you can use, <literal>ObjectNameAutoProxyCreator</literal>
|
||||
and <literal>DefaultAdvisorAutoProxyCreator</literal>. If you are using
|
||||
the new transaction namespace support you do not need to configure these
|
||||
objects as a DefaultAdvisorAutoProxyCreator is created 'under the
|
||||
covers' while parsing the transaction namespace elements</para>
|
||||
@@ -1759,8 +1798,7 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Using a
|
||||
<literal>IPlatformTransactionManager</literal>
|
||||
<para>Using a <literal>IPlatformTransactionManager</literal>
|
||||
implementation directly</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
@@ -1775,16 +1813,16 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
|
||||
<para>The TransactionTemplate adopts the same approach as other Spring
|
||||
templates such as <literal>AdoTemplate</literal> and
|
||||
<literal>HibernateTemplate</literal>. It uses a callback approach,
|
||||
to free application code from having to do the boilerplate acquisition
|
||||
and release of resources, and results in code that is intention driven,
|
||||
in that the code that is written focuses solely on what the developer
|
||||
wants to do. Granted that the using construct of System.Transaction
|
||||
alleviates much of this. One key difference with the approach taken with
|
||||
the TransactionTemplate is that a commit is assumed - throwing an
|
||||
exception triggers a rollback instead of using the TransactionScope API
|
||||
to commit or rollback. This also allows for the use of rollback rules,
|
||||
that is a commit can still occur for exceptions of certain types. <note>
|
||||
<literal>HibernateTemplate</literal>. It uses a callback approach, to
|
||||
free application code from having to do the boilerplate acquisition and
|
||||
release of resources, and results in code that is intention driven, in
|
||||
that the code that is written focuses solely on what the developer wants
|
||||
to do. Granted that the using construct of System.Transaction alleviates
|
||||
much of this. One key difference with the approach taken with the
|
||||
TransactionTemplate is that a commit is assumed - throwing an exception
|
||||
triggers a rollback instead of using the TransactionScope API to commit
|
||||
or rollback. This also allows for the use of rollback rules, that is a
|
||||
commit can still occur for exceptions of certain types. <note>
|
||||
<para>As you will immediately see in the examples that follow, using
|
||||
the <literal>TransactionTemplate</literal> absolutely couples you to
|
||||
Spring's transaction infrastructure and APIs. Whether or not
|
||||
@@ -1799,8 +1837,8 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
execute in the context of a transaction. You will then pass an instance
|
||||
of your custom ITransactionCallback to the Execute(..) method exposed on
|
||||
the TransactionTemplate. Note that the
|
||||
<literal>ITransactionCallback</literal> can be used to
|
||||
return a value:</para>
|
||||
<literal>ITransactionCallback</literal> can be used to return a
|
||||
value:</para>
|
||||
|
||||
<programlisting language="csharp">public class SimpleService : IService
|
||||
{
|
||||
@@ -1826,11 +1864,10 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
delegates, which provides a particularly elegant means to invoke a
|
||||
callback function as local variables can be referred to inside the
|
||||
delegate, i.e. userId. In this case the
|
||||
<literal>ITransactionStatus</literal> was not exposed in the
|
||||
delegate (delegate can infer the signature to use), but one could also
|
||||
obtain a reference to the
|
||||
<literal>ITransactionStatus</literal> instance and set the
|
||||
<literal>RollbackOnly</literal> property to trigger a rollback - or
|
||||
<literal>ITransactionStatus</literal> was not exposed in the delegate
|
||||
(delegate can infer the signature to use), but one could also obtain a
|
||||
reference to the <literal>ITransactionStatus</literal> instance and set
|
||||
the <literal>RollbackOnly</literal> property to trigger a rollback - or
|
||||
alternatively throw an exception. This is shown below</para>
|
||||
|
||||
<programlisting language="csharp">tt.Execute(delegate(ITransactionStatus status)
|
||||
@@ -1846,8 +1883,8 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
|
||||
<para>If you are using .NET 1.1 then you should provide a normal
|
||||
delegate reference or an instance of a class that implements the
|
||||
<literal>ITransactionCallback</literal> interface. This is
|
||||
shown below</para>
|
||||
<literal>ITransactionCallback</literal> interface. This is shown
|
||||
below</para>
|
||||
|
||||
<programlisting language="csharp">tt.Execute(new TransactionRollbackTxCallback(amount));
|
||||
|
||||
@@ -1872,9 +1909,9 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
|
||||
<para>Application classes wishing to use the
|
||||
<literal>TransactionTemplate</literal> must have access to a
|
||||
<literal>IPlatformTransactionManager</literal> (which will
|
||||
typically be supplied to the class via dependency injection). It is easy
|
||||
to unit test such classes with a mock or stub
|
||||
<literal>IPlatformTransactionManager</literal> (which will typically be
|
||||
supplied to the class via dependency injection). It is easy to unit test
|
||||
such classes with a mock or stub
|
||||
<literal>IPlatformTransactionManager</literal>.</para>
|
||||
|
||||
<sect3>
|
||||
@@ -1882,11 +1919,11 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
|
||||
<para>Transaction settings such as the propagation mode, the isolation
|
||||
level, the timeout, and so forth can be set on the
|
||||
<literal>TransactionTemplate</literal> either programmatically or
|
||||
in configuration. <literal>TransactionTemplate</literal> instances
|
||||
by default have the default transactional settings. Find below an
|
||||
example of programmatically customizing the transactional settings for
|
||||
a specific <literal>TransactionTemplate</literal>.</para>
|
||||
<literal>TransactionTemplate</literal> either programmatically or in
|
||||
configuration. <literal>TransactionTemplate</literal> instances by
|
||||
default have the default transactional settings. Find below an example
|
||||
of programmatically customizing the transactional settings for a
|
||||
specific <literal>TransactionTemplate</literal>.</para>
|
||||
|
||||
<programlisting language="csharp">public class SimpleService : IService
|
||||
{
|
||||
@@ -1912,8 +1949,8 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
</programlisting>
|
||||
|
||||
<para>Find below an example of defining a
|
||||
<literal>TransactionTemplate</literal> with some custom
|
||||
transactional settings, using Spring XML configuration. The
|
||||
<literal>TransactionTemplate</literal> with some custom transactional
|
||||
settings, using Spring XML configuration. The
|
||||
'<literal>sharedTransactionTemplate</literal>' can then be injected
|
||||
into as many services as are required.</para>
|
||||
|
||||
@@ -1923,15 +1960,14 @@ mgr.DeleteTwoTestObjects("Jack", "Jill");
|
||||
<property name="TransactionTimeout" value="30"/>
|
||||
</object></programlisting>
|
||||
|
||||
<para>Finally, instances of the
|
||||
<literal>TransactionTemplate</literal> class are threadsafe, in
|
||||
that instances do not maintain any conversational state.
|
||||
<literal>TransactionTemplate</literal> instances do however
|
||||
maintain configuration state, so while a number of classes may choose
|
||||
to share a single instance of a
|
||||
<para>Finally, instances of the <literal>TransactionTemplate</literal>
|
||||
class are threadsafe, in that instances do not maintain any
|
||||
conversational state. <literal>TransactionTemplate</literal> instances
|
||||
do however maintain configuration state, so while a number of classes
|
||||
may choose to share a single instance of a
|
||||
<literal>TransactionTemplate</literal>, if a class needed to use a
|
||||
<literal>TransactionTemplate</literal> with different settings
|
||||
(for example, a different isolation level), then two distinct
|
||||
<literal>TransactionTemplate</literal> with different settings (for
|
||||
example, a different isolation level), then two distinct
|
||||
<literal>TransactionTemplate</literal> instances would need to be
|
||||
created and used.</para>
|
||||
</sect3>
|
||||
@@ -1991,10 +2027,10 @@ transactionManager.Commit(status);</programlisting>
|
||||
Typical application code should not need to rely on using this class but
|
||||
in some cases it is convenient to receive events around the lifecycle of
|
||||
the transaction, i.e. before committing, after committing.
|
||||
<literal>TransactionSynchronizationManager</literal> provides a method
|
||||
to register a callback object that is informed on all significant stages
|
||||
in the transaction lifecycle. Note that you can register for lifecycle
|
||||
call back information for any of the transaction managers you use, be it
|
||||
<literal>TransactionSynchronizationManager</literal> provides a method to
|
||||
register a callback object that is informed on all significant stages in
|
||||
the transaction lifecycle. Note that you can register for lifecycle call
|
||||
back information for any of the transaction managers you use, be it
|
||||
NHibernate or local ADO.NET transactions.</para>
|
||||
|
||||
<para>The method to register a callback with the
|
||||
@@ -2023,7 +2059,7 @@ transactionManager.Commit(status);</programlisting>
|
||||
void AfterCompletion( TransactionSynchronizationStatus status );
|
||||
}</programlisting>
|
||||
|
||||
<para>The <literal>TransactionSynchronizationStatus</literal> is an
|
||||
enum with the values Committed, Rolledback, and Unknown.</para>
|
||||
<para>The <literal>TransactionSynchronizationStatus</literal> is an enum
|
||||
with the values Committed, Rolledback, and Unknown.</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
</chapter>
|
||||
|
||||
Reference in New Issue
Block a user