You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by aw...@apache.org on 2006/08/24 22:41:14 UTC
svn commit: r434517 [9/23] - in /incubator/openjpa/trunk:
openjpa-kernel/src/main/java/org/apache/openjpa/meta/
openjpa-lib/src/main/java/org/apache/openjpa/lib/meta/
openjpa-project/src/doc/manual/
Modified: incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_sqlquery.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_sqlquery.xml?rev=434517&r1=434516&r2=434517&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_sqlquery.xml (original)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_sqlquery.xml Thu Aug 24 13:41:12 2006
@@ -1,135 +1,195 @@
-
- <chapter id="jpa_overview_sqlquery">
- <title>SQL Queries</title>
- <indexterm zone="jpa_overview_sqlquery">
- <primary>SQL queries</primary>
- <seealso>Query</seealso>
- </indexterm>
- <indexterm>
- <primary>Query</primary>
- <secondary>SQL</secondary>
- <see>SQL queries</see>
- </indexterm>
- <indexterm>
- <primary>SQL</primary>
- <secondary>queries</secondary>
- <see>SQL queries</see>
- </indexterm>
- <indexterm>
- <primary>Native</primary>
- <secondary>queries</secondary>
- <see>SQL queries</see>
- </indexterm>
- <para>
- JPQL is a powerful query language, but there are times when it is
- not enough. Maybe you're migrating a JDBC application to JPA
- on a strict deadline, and you don't have time to translate your existing
- SQL selects to JPQL. Or maybe a certain query requires
- database-specific SQL your JPA implementation doesn't support.
- Or maybe your DBA has spent hours crafting the perfect select statement
- for a query in your application's critical path. Whatever the reason, SQL
- queries can remain an essential part of an application.
- </para>
- <para>
- You are probably familiar with executing SQL queries by obtaining a
- <classname>java.sql.Connection</classname>, using the JDBC APIs to create
- a <classname>Statement</classname>, and executing that <classname>Statement
- </classname> to obtain a <classname>ResultSet</classname>. And of course,
- you are free to continue using this low-level approach to SQL execution in
- your JPA applications. However, JPA also supports executing SQL queries
- through the <classname>javax.persistence.Query</classname>
- interface introduced in <xref linkend="jpa_overview_query"/>.
- Using a JPA SQL query, you can retrieve either persistent objects
- or projections of column values. The following sections detail each use.
- </para>
- <section id="jpa_overview_sqlquery_create">
- <title>Creating SQL Queries</title>
+<chapter id="jpa_overview_sqlquery">
+ <title>
+ SQL Queries
+ </title>
+ <indexterm zone="jpa_overview_sqlquery">
+ <primary>
+ SQL queries
+ </primary>
+ <seealso>
+ Query
+ </seealso>
+ </indexterm>
+ <indexterm>
+ <primary>
+ Query
+ </primary>
+ <secondary>
+ SQL
+ </secondary>
+ <see>
+ SQL queries
+ </see>
+ </indexterm>
+ <indexterm>
+ <primary>
+ SQL
+ </primary>
+ <secondary>
+ queries
+ </secondary>
+ <see>
+ SQL queries
+ </see>
+ </indexterm>
+ <indexterm>
+ <primary>
+ Native
+ </primary>
+ <secondary>
+ queries
+ </secondary>
+ <see>
+ SQL queries
+ </see>
+ </indexterm>
+ <para>
+JPQL is a powerful query language, but there are times when it is not enough.
+Maybe you're migrating a JDBC application to JPA on a strict deadline, and you
+don't have time to translate your existing SQL selects to JPQL. Or maybe a
+certain query requires database-specific SQL your JPA implementation doesn't
+support. Or maybe your DBA has spent hours crafting the perfect select statement
+for a query in your application's critical path. Whatever the reason, SQL
+queries can remain an essential part of an application.
+ </para>
+ <para>
+You are probably familiar with executing SQL queries by obtaining a <classname>
+java.sql.Connection</classname>, using the JDBC APIs to create a <classname>
+Statement</classname>, and executing that <classname>Statement</classname> to
+obtain a <classname>ResultSet</classname>. And of course, you are free to
+continue using this low-level approach to SQL execution in your JPA
+applications. However, JPA also supports executing SQL queries through the
+<classname>javax.persistence.Query</classname> interface introduced in
+<xref linkend="jpa_overview_query"></xref>. Using a JPA SQL query, you can
+retrieve either persistent objects or projections of column values. The
+following sections detail each use.
+ </para>
+ <section id="jpa_overview_sqlquery_create">
+ <title>
+ Creating SQL Queries
+ </title>
<indexterm zone="jpa_overview_sqlquery_create">
- <primary>SQL queries</primary>
- <secondary>creating</secondary>
+ <primary>
+ SQL queries
+ </primary>
+ <secondary>
+ creating
+ </secondary>
</indexterm>
<para>
- The <classname>EntityManager</classname> has two factory methods
- suitable for creating SQL queries:
- </para>
- <programlisting format="linespecific">
+The <classname>EntityManager</classname> has two factory methods suitable for
+creating SQL queries:
+ </para>
+<programlisting>
public Query createNativeQuery (String sqlString, Class resultClass);
public Query createNativeQuery (String sqlString, String resultSetMapping);
</programlisting>
<para>
- The first method is used to create a new <classname>Query</classname>
- instance that will return instances of the specified class.
- </para>
- <para>
- The second method uses a <literal>SqlResultSetMapping</literal>
- to determine the type of object or objects to return.
- The example below shows these methods in action.
- </para>
+The first method is used to create a new <classname>Query</classname> instance
+that will return instances of the specified class.
+ </para>
+ <para>
+The second method uses a <literal>SqlResultSetMapping</literal> to determine the
+type of object or objects to return. The example below shows these methods in
+action.
+ </para>
<example id="jpa_overview_sqlquery_createex">
- <title>Creating a SQL Query</title>
- <programlisting format="linespecific">
+ <title>
+ Creating a SQL Query
+ </title>
+<programlisting>
EntityManager em = ...;
Query query = em.createNativeQuery ("SELECT * FROM MAG", Magazine.class);
processMagazines (query.getResultList ());
</programlisting>
</example>
<note>
- <para><indexterm><primary>SQL queries</primary><secondary>stored procedures</secondary></indexterm><indexterm><primary>stored procedures</primary><secondary>as queries</secondary><seealso>Query</seealso></indexterm>
- In addition to SELECT statements, OpenJPA supports stored procedure
- invocations as SQL queries. OpenJPA will assume any SQL that does
- not begin with the <literal>SELECT</literal> keyword (ignoring
- case) is a stored procedure call, and invoke it as such at the
- JDBC level.
- </para>
+ <para>
+ <indexterm>
+ <primary>
+ SQL queries
+ </primary>
+ <secondary>
+ stored procedures
+ </secondary>
+ </indexterm>
+ <indexterm>
+ <primary>
+ stored procedures
+ </primary>
+ <secondary>
+ as queries
+ </secondary>
+ <seealso>
+ Query
+ </seealso>
+ </indexterm>
+In addition to SELECT statements, OpenJPA supports stored procedure invocations
+as SQL queries. OpenJPA will assume any SQL that does not begin with the
+<literal>SELECT</literal> keyword (ignoring case) is a stored procedure call,
+and invoke it as such at the JDBC level.
+ </para>
</note>
- </section>
- <section id="jpa_overview_sqlquery_obj">
- <title>Retrieving Persistent Objects with SQL</title>
+ </section>
+ <section id="jpa_overview_sqlquery_obj">
+ <title>
+ Retrieving Persistent Objects with SQL
+ </title>
<indexterm zone="jpa_overview_sqlquery_obj">
- <primary>SQL queries</primary>
- <secondary>retrieving persistent objects</secondary>
+ <primary>
+ SQL queries
+ </primary>
+ <secondary>
+ retrieving persistent objects
+ </secondary>
</indexterm>
<indexterm zone="jpa_overview_sqlquery_obj">
- <primary>persistent objects</primary>
- <secondary>retrieving with SQL</secondary>
- <seealso>SQL queries</seealso>
+ <primary>
+ persistent objects
+ </primary>
+ <secondary>
+ retrieving with SQL
+ </secondary>
+ <seealso>
+ SQL queries
+ </seealso>
</indexterm>
<para>
- When you give a SQL <classname>Query</classname> a candidate class, it
- will return persistent instances of that class. At a minimum, your
- SQL must select the
- class' primary key columns, discriminator column (if mapped), and
- version column (also if mapped). The JPA runtime uses the values
- of the primary key columns to construct each result object's identity,
- and possibly to match it with a persistent object already in the
- <classname>EntityManager</classname>'s cache. When an object is
- not already cached, the
- implementation creates a new object to represent the current result
- row. It might use the discriminator column value to make sure it
- constructs an object of the correct subclass. Finally, the query
- records available version column data for use in optimistic concurrency
- checking, should you later change the result object and flush it back
- to the database.
- </para>
- <para>
- Aside from the primary key, discriminator, and version columns, any
- columns you select are used to populate the persistent fields of each
- result object. JPA implementations will compete on how effectively
- they map your selected data to your persistent instance fields.
- </para>
- <para>
- Let's make the discussion above concrete with an example. It uses
- the following simple mapping between a class and the database:
- </para>
+When you give a SQL <classname>Query</classname> a candidate class, it will
+return persistent instances of that class. At a minimum, your SQL must select
+the class' primary key columns, discriminator column (if mapped), and version
+column (also if mapped). The JPA runtime uses the values of the primary key
+columns to construct each result object's identity, and possibly to match it
+with a persistent object already in the <classname>EntityManager</classname>'s
+cache. When an object is not already cached, the implementation creates a new
+object to represent the current result row. It might use the discriminator
+column value to make sure it constructs an object of the correct subclass.
+Finally, the query records available version column data for use in optimistic
+concurrency checking, should you later change the result object and flush it
+back to the database.
+ </para>
+ <para>
+Aside from the primary key, discriminator, and version columns, any columns you
+select are used to populate the persistent fields of each result object. JPA
+implementations will compete on how effectively they map your selected data to
+your persistent instance fields.
+ </para>
+ <para>
+Let's make the discussion above concrete with an example. It uses the following
+simple mapping between a class and the database:
+ </para>
<mediaobject>
- <imageobject>
-<!-- PNG image data, 320 x 149 (see README) -->
- <imagedata fileref="img/sqlquery-model.png" width="213px"/>
- </imageobject>
+ <imageobject>
+ <!-- PNG image data, 320 x 149 (see README) -->
+ <imagedata fileref="img/sqlquery-model.png" width="213px">
+ </imagedata>
+ </imageobject>
</mediaobject>
<example id="jpa_overview_sqlquery_objex">
- <title>Retrieving Persistent Objects</title>
- <programlisting format="linespecific">
+ <title>
+ Retrieving Persistent Objects
+ </title>
+<programlisting>
Query query = em.createNativeQuery ("SELECT ISBN, TITLE, PRICE, "
+ "VERS FROM MAG WHERE PRICE > 5 AND PRICE < 10", Magazine.class);
List<Magazine> results = query.getResultList ();
@@ -138,13 +198,15 @@
</programlisting>
</example>
<para>
- The query above works as advertised, but isn't very flexible. Let's
- update it to take in parameters for the minimum and maximum price,
- so we can reuse it to find magazines in any price range:
- </para>
+The query above works as advertised, but isn't very flexible. Let's update it to
+take in parameters for the minimum and maximum price, so we can reuse it to find
+magazines in any price range:
+ </para>
<example id="jpa_overview_sqlquery_obj_paramex">
- <title>SQL Query Parameters</title>
- <programlisting format="linespecific">
+ <title>
+ SQL Query Parameters
+ </title>
+<programlisting>
Query query = em.createNativeQuery ("SELECT ISBN, TITLE, PRICE, "
+ "VERS FROM MAG WHERE PRICE > ?1 AND PRICE < ?2", Magazine.class);
@@ -156,183 +218,28 @@
processMagazine (mag);
</programlisting>
</example>
- <para><indexterm><primary>SQL queries</primary><secondary>parameters</secondary></indexterm><indexterm><primary>parameters</primary><secondary>in SQL queries</secondary><seealso>SQL queries</seealso></indexterm>
- Like JDBC prepared statements, SQL queries represent parameters with
- question marks, but are followed by an integer to represent its
- index.
- </para>
- </section>
-<!--
- <section id="jpa_overview_sqlquery_proj">
- <title>SQL Projections</title>
- <indexterm zone="jpa_overview_sqlquery_proj">
- <primary>SQL queries</primary>
- <secondary>projections</secondary>
- </indexterm>
- <indexterm zone="jpa_overview_sqlquery_proj">
- <primary>projections</primary>
- <secondary>of column data</secondary>
- <seealso>SQL queries</seealso>
- </indexterm>
- <para>
- SQL queries without a candidate class are treated as projections of
- column data. If you select a single column, the query returns
- a list of <classname>Object</classname>s. If you select multiple
- columns, it returns a list of <classname>Object[]</classname>s.
- In either case, each column value is obtained using the
- <methodname>java.sql.ResultSet.getObject</methodname> method. The
- following example demonstrates a query for the values of the
- <literal>ISBN</literal> and <literal>VERS</literal> columns of all
- <literal>MAG</literal> table records, using the data model we
- defined in <xref linkend="jpa_overview_sqlquery_obj"/>.
- </para>
- <example id="jpa_overview_sqlquery_projex">
- <title>Column Projection</title>
-<programlisting>
-Query query = em.newQuery ("javax.persistence.query.SQL",
- "SELECT ISBN, VERS FROM MAG");
-List results = query.getResultList ();
-for (Iterator itr = results.iterator (); itr.hasNext ();)
-{
- Object[] data = (Object[]) results.next ();
- processISBNAndVersion (data[0], data[1]);
-}
-</programlisting>
- <para>
- Notice that in the code above, we did not set a candidate class.
- Therefore, the query is treated as a projection.
- </para>
- </example>
- <para>
- <indexterm>
- <primary>SQL queries</primary>
- <secondary>result class</secondary>
- </indexterm>
- Our discussion of JPQL query result classes in
- <xref linkend="jpa_overview_query_resultcls"/> also
- applies to SQL queries. As with JPQL queries, SQL queries can
- automatically pack their results into objects of a specified type.
- JPA uses the <methodname>java.sql.ResultSetMetaData.getColumnLabel
- </methodname> method to match each column alias to the result class'
- public fields and JavaBean setter methods. Here is a modification of
- our example above that packs the selected column values into JavaBean
- instances.
- </para>
- <example id="jpa_overview_sqlquery_proj_labelex">
- <title>Result Class</title>
-<programlisting>
-public class Identity
-{
- private String id;
- private int versionNumber;
-
- public void setId (String id)
- {
- this.id = id;
- }
-
- public String getId ()
- {
- return id;
- }
-
- public void setVersionNumber (int versionNumber)
- {
- this.versionNumber = versionNumber;
- }
-
- public int getVersionNumber ()
- {
- return versionNumber;
- }
-}
-
-Query query = em.createNativeQuery ("javax.persistence.query.SQL",
- "SELECT ISBN AS id, VERS AS versionNumber FROM MAG", Identity.class);
-List results = query.getResultList ();
-for (Iterator itr = results.iterator (); itr.hasNext ();)
- processIdentity ((Identity) itr.next ());
-</programlisting>
- </example>
- </section>
- <section id="jpa_overview_sqlquery_named">
- <title>Named SQL Queries</title>
- <indexterm zone="jpa_overview_sqlquery_named">
- <primary>SQL queries</primary>
- <secondary>named</secondary>
- <see>named queries</see>
- </indexterm>
- <indexterm zone="jpa_overview_sqlquery_named">
- <primary>named queries</primary>
- <secondary>SQL</secondary>
- </indexterm>
- <para>
- We discussed how to write named JPQL queries in
- <xref linkend="jpa_overview_query_named"/>. Named queries, however,
- are not limited to JPQL. By setting the <literal>query</literal>
- element's <literal>language</literal> attribute to <literal>
- javax.persistence.query.SQL</literal>, you can define a named SQL query. A
- named SQL query within a <literal>class</literal> element queries for
- instances of that class; a named SQL query outside of a <literal>class
- </literal> element acts as a column data projection.
- </para>
- <example id="jpa_overview_sqlquery_namedex">
- <title>Named SQL Queries</title>
-<programlisting>
-<![CDATA[<?xml version="1.0"?>
-<jdoquery>
- <query name="salesReport" language="javax.persistence.query.SQL">
- SELECT TITLE, PRICE * COPIES FROM MAG
- </query>
- <package name="org.mag">
- <class name="Magazine">
- <query name="findByTitle" language="javax.persistence.query.SQL">
- SELECT * FROM MAG WHERE TITLE = ?
- </query>
- </class>
- </package>
-</jdoquery>]]>
-</programlisting>
- <para>
- The <literal>salesReport</literal> query above returns the title
- and revenue generated for each <classname>Magazine</classname>.
- Because it is a projection, it does not have a candidate class, and
- so we specify it at the root level.
- </para>
- <para>
- The <literal>findByTitle</literal> query returns the <classname>
- Magazine</classname> with the title given on execution. The code
- below executes both queries.
- </para>
-<programlisting>
-EntityManager em = ...;
-Query query = em.newNamedQuery (null, "salesReport");
-List sales = query.getResultList ();
-for (Iterator itr = sales.iterator (); itr.hasNext ();)
-{
- Object[] salesData = (Object[]) itr.next ();
- processSalesData ((String) salesData[0], (Number) salesData[1]);
-}
-
-query = em.newNamedQuery (Magazine.class, "findByTitle");
-query.setUnique (true);
-Magazine jdj = (Magazine) query.execute ("JDJ");
-</programlisting>
- </example>
- </section>
- <section id="jpa_overview_sqlquery_conclusion">
- <title>Conclusion</title>
- <para>
- If you've used relational databases extensively, you might be tempted
- to perform all your JPA queries with SQL. Try to resist this
- temptation. SQL queries tie your application to the particulars of
- your current table model and database vendor. If you stick with JPQL,
- on the other hand, you can port your application to other schemas and
- database vendors without any changes to your code. Additionally,
- most JPA implementations already produce highly optimized SQL from
- your JPQL filters, and many are able to cache JPQL query results
- for added performance.
- </para>
- </section>
- -->
- </chapter>
+ <para>
+ <indexterm>
+ <primary>
+ SQL queries
+ </primary>
+ <secondary>
+ parameters
+ </secondary>
+ </indexterm>
+ <indexterm>
+ <primary>
+ parameters
+ </primary>
+ <secondary>
+ in SQL queries
+ </secondary>
+ <seealso>
+ SQL queries
+ </seealso>
+ </indexterm>
+Like JDBC prepared statements, SQL queries represent parameters with question
+marks, but are followed by an integer to represent its index.
+ </para>
+ </section>
+</chapter>
Modified: incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_trans.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_trans.xml?rev=434517&r1=434516&r2=434517&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_trans.xml (original)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_trans.xml Thu Aug 24 13:41:12 2006
@@ -1,214 +1,403 @@
-
- <chapter id="jpa_overview_trans">
- <title>Transaction</title>
- <indexterm zone="jpa_overview_trans">
- <primary>transactions</primary>
- <seealso>Transaction</seealso>
- </indexterm>
- <para>
- Transactions are critical to maintaining data integrity. They are
- used to group operations into units of work that act in an
- all-or-nothing fashion. Transactions have the following qualities:
- </para>
- <itemizedlist>
+<chapter id="jpa_overview_trans">
+ <title>
+ Transaction
+ </title>
+ <indexterm zone="jpa_overview_trans">
+ <primary>
+ transactions
+ </primary>
+ <seealso>
+ Transaction
+ </seealso>
+ </indexterm>
+ <para>
+Transactions are critical to maintaining data integrity. They are used to group
+operations into units of work that act in an all-or-nothing fashion.
+Transactions have the following qualities:
+ </para>
+ <itemizedlist>
<listitem>
- <para><indexterm><primary>atomicity</primary><seealso>transactions</seealso></indexterm><indexterm><primary>transactions</primary><secondary>atomicity</secondary></indexterm><emphasis>Atomicity</emphasis>. Atomicity refers to the
- all-or-nothing property of transactions. Either every
- data update in the transaction completes successfully, or they
- all fail, leaving the datastore in its original state. A
- transaction cannot be only partially successful.
- </para>
+ <para>
+ <indexterm>
+ <primary>
+ atomicity
+ </primary>
+ <seealso>
+ transactions
+ </seealso>
+ </indexterm>
+ <indexterm>
+ <primary>
+ transactions
+ </primary>
+ <secondary>
+ atomicity
+ </secondary>
+ </indexterm>
+<emphasis>Atomicity</emphasis>. Atomicity refers to the all-or-nothing property
+of transactions. Either every data update in the transaction completes
+successfully, or they all fail, leaving the datastore in its original state. A
+transaction cannot be only partially successful.
+ </para>
</listitem>
<listitem>
- <para><indexterm><primary>consistency</primary><seealso>transactions</seealso></indexterm><indexterm><primary>transactions</primary><secondary>consistency</secondary></indexterm><emphasis>Consistency</emphasis>. Each transaction takes the
- datastore from one consistent state to another consistent
- state.
- </para>
+ <para>
+ <indexterm>
+ <primary>
+ consistency
+ </primary>
+ <seealso>
+ transactions
+ </seealso>
+ </indexterm>
+ <indexterm>
+ <primary>
+ transactions
+ </primary>
+ <secondary>
+ consistency
+ </secondary>
+ </indexterm>
+<emphasis>Consistency</emphasis>. Each transaction takes the datastore from one
+consistent state to another consistent state.
+ </para>
</listitem>
<listitem>
- <para><indexterm><primary>isolation</primary><seealso>transactions</seealso></indexterm><indexterm><primary>transactions</primary><secondary>isolation</secondary></indexterm><emphasis>Isolation</emphasis>. Transactions are isolated from
- each other. When you are reading persistent data in one
- transaction, you cannot "see" the changes that are being made
- to that data in other transactions. Similarly,
- the updates you make in one transaction cannot conflict with
- updates made in concurrent transactions. The form of
- conflict resolution employed depends on whether you are using
- pessimistic or optimistic transactions. Both types are
- described later in this chapter.
- </para>
+ <para>
+ <indexterm>
+ <primary>
+ isolation
+ </primary>
+ <seealso>
+ transactions
+ </seealso>
+ </indexterm>
+ <indexterm>
+ <primary>
+ transactions
+ </primary>
+ <secondary>
+ isolation
+ </secondary>
+ </indexterm>
+<emphasis>Isolation</emphasis>. Transactions are isolated from each other. When
+you are reading persistent data in one transaction, you cannot "see" the changes
+that are being made to that data in other transactions. Similarly, the updates
+you make in one transaction cannot conflict with updates made in concurrent
+transactions. The form of conflict resolution employed depends on whether you
+are using pessimistic or optimistic transactions. Both types are described later
+in this chapter.
+ </para>
</listitem>
<listitem>
- <para><indexterm><primary>durability</primary><seealso>transactions</seealso></indexterm><indexterm><primary>transactions</primary><secondary>durability</secondary></indexterm><emphasis>Durability</emphasis>. The effects of successful
- transactions are durable; the updates made to persistent data
- last for the lifetime of the datastore.
- </para>
+ <para>
+ <indexterm>
+ <primary>
+ durability
+ </primary>
+ <seealso>
+ transactions
+ </seealso>
+ </indexterm>
+ <indexterm>
+ <primary>
+ transactions
+ </primary>
+ <secondary>
+ durability
+ </secondary>
+ </indexterm>
+<emphasis>Durability</emphasis>. The effects of successful transactions are
+durable; the updates made to persistent data last for the lifetime of the
+datastore.
+ </para>
</listitem>
- </itemizedlist>
- <para><indexterm><primary>ACID</primary><seealso>transactions</seealso></indexterm><indexterm><primary>transactions</primary><secondary>ACID</secondary></indexterm>
- Together, these qualities are called the ACID properties of
- transactions. To understand why these properties are so important
- to maintaining data integrity, consider the following example:
- </para>
- <para>
- Suppose you create an application to manage bank accounts. The
- application includes a method to transfer funds from one user to
- another, and it looks something like this:
- </para>
- <programlisting format="linespecific">
+ </itemizedlist>
+ <para>
+ <indexterm>
+ <primary>
+ ACID
+ </primary>
+ <seealso>
+ transactions
+ </seealso>
+ </indexterm>
+ <indexterm>
+ <primary>
+ transactions
+ </primary>
+ <secondary>
+ ACID
+ </secondary>
+ </indexterm>
+Together, these qualities are called the ACID properties of transactions. To
+understand why these properties are so important to maintaining data integrity,
+consider the following example:
+ </para>
+ <para>
+Suppose you create an application to manage bank accounts. The application
+includes a method to transfer funds from one user to another, and it looks
+something like this:
+ </para>
+<programlisting>
public void transferFunds (User from, User to, double amnt)
{
from.decrementAccount (amnt);
to.incrementAccount (amnt);
}
</programlisting>
- <para>
- Now suppose that user Alice wants to transfer 100 dollars to user Bob.
- No problem; you simply invoke your
- <methodname>transferFunds</methodname> method, supplying Alice in the
- <literal>from</literal> parameter, Bob in the <literal>to</literal>
- parameter, and <literal>100.00</literal> as the <literal>amnt</literal>.
- The first line of the method is executed, and 100 dollars is subtracted
- from Alice's account. But then, something goes wrong. An unexpected
- exception occurs, or the hardware fails, and your method never
- completes.
- </para>
- <para>
- You are left with a situation in which the 100 dollars has simply
- disappeared. Thanks to the first line of your method, it is no longer
- in Alice's account, and yet it was never transferred to Bob's account
- either. The datastore is in an inconsistent state.
- </para>
- <para>
- The importance of transactions should now be clear. If the two lines
- of the <methodname>transferFunds</methodname> method had been placed
- together in a transaction, it would be impossible for only the
- first line to succeed. Either the funds would be transferred
- properly or they would not be transferred at all, and an exception
- would be thrown. Money could never vanish into thin air, and the data
- store could never get into an inconsistent state.
- </para>
- <section id="jpa_overview_trans_types">
- <title>Transaction Types</title>
+ <para>
+Now suppose that user Alice wants to transfer 100 dollars to user Bob. No
+problem; you simply invoke your <methodname>transferFunds</methodname> method,
+supplying Alice in the <literal>from</literal> parameter, Bob in the <literal>
+to</literal> parameter, and <literal>100.00</literal> as the <literal>amnt
+</literal>. The first line of the method is executed, and 100 dollars is
+subtracted from Alice's account. But then, something goes wrong. An unexpected
+exception occurs, or the hardware fails, and your method never completes.
+ </para>
+ <para>
+You are left with a situation in which the 100 dollars has simply disappeared.
+Thanks to the first line of your method, it is no longer in Alice's account, and
+yet it was never transferred to Bob's account either. The datastore is in an
+inconsistent state.
+ </para>
+ <para>
+The importance of transactions should now be clear. If the two lines of the
+<methodname>transferFunds</methodname> method had been placed together in a
+transaction, it would be impossible for only the first line to succeed. Either
+the funds would be transferred properly or they would not be transferred at all,
+and an exception would be thrown. Money could never vanish into thin air, and
+the data store could never get into an inconsistent state.
+ </para>
+ <section id="jpa_overview_trans_types">
+ <title>
+ Transaction Types
+ </title>
<indexterm zone="jpa_overview_trans_types">
- <primary>transactions</primary>
- <secondary>types</secondary>
+ <primary>
+ transactions
+ </primary>
+ <secondary>
+ types
+ </secondary>
</indexterm>
<para>
- There are two major types of transactions: pessimistic transactions
- and optimistic transactions. Each type has both advantages and
- disadvantages.
- </para>
- <para><indexterm><primary>transactions</primary><secondary>pessimistic</secondary></indexterm><indexterm><primary>pessimistic transactions</primary><see>transactions, pessimistic</see></indexterm><indexterm><primary>deadlock</primary><seealso>transactions</seealso></indexterm>
- Pessimistic transactions generally lock the datastore records they
- act on, preventing other concurrent transactions from using the
- same data. This avoids conflicts between transactions, but
- consumes database resources. Additionally, locking records
- can result in <emphasis>deadlock</emphasis>, a situation in which two
- transactions are both waiting for the other to release its locks before
- completing. The results of a deadlock are datastore-dependent;
- usually one transaction is forcefully rolled back after some specified
- timeout interval, and an exception is thrown.
- </para>
- <para><indexterm><primary>transactions</primary><secondary>datastore</secondary></indexterm><indexterm><primary>datastore transactions</primary><see>transactions, datastore</see></indexterm>
- This document will often use the term <emphasis>datastore</emphasis>
- transaction in place of <emphasis>pessimistic</emphasis> transaction.
- This is to acknowledge that some datastores do not support pessimistic
- semantics, and that the exact meaning of a non-optimistic JPA
- transaction is dependent on the datastore. Most of the
- time, a datastore transaction is equivalent to a pessimistic
- transaction.
- </para>
- <para><indexterm><primary>transactions</primary><secondary>optimistic</secondary></indexterm><indexterm><primary>optimistic transactions</primary><see>transactions, optimistic</see></indexterm>
- Optimistic transactions consume less resources than
- pessimistic/datastore transactions, but only at the expense of
- reliability. Because optimistic transactions do not lock datastore
- records, two transactions might change the same persistent information
- at the same time, and the conflict will not be detected until
- the second transaction attempts to flush or commit. At this time, the
- second transaction will realize that another transaction has
- concurrently modified the same records (usually through a timestamp
- or versioning system), and will throw an appropriate exception.
- Note that optimistic transactions still maintain data integrity;
- they are simply more likely to fail in heavily concurrent
- situations.
- </para>
- <para>
- Despite their drawbacks, optimistic transactions are the best choice
- for most applications. They offer better performance, better
- scalability, and lower risk of hanging due to deadlock.
- </para>
+There are two major types of transactions: pessimistic transactions and
+optimistic transactions. Each type has both advantages and disadvantages.
+ </para>
+ <para>
+ <indexterm>
+ <primary>
+ transactions
+ </primary>
+ <secondary>
+ pessimistic
+ </secondary>
+ </indexterm>
+ <indexterm>
+ <primary>
+ pessimistic transactions
+ </primary>
+ <see>
+ transactions, pessimistic
+ </see>
+ </indexterm>
+ <indexterm>
+ <primary>
+ deadlock
+ </primary>
+ <seealso>
+ transactions
+ </seealso>
+ </indexterm>
+Pessimistic transactions generally lock the datastore records they act on,
+preventing other concurrent transactions from using the same data. This avoids
+conflicts between transactions, but consumes database resources. Additionally,
+locking records can result in <emphasis>deadlock</emphasis>, a situation in
+which two transactions are both waiting for the other to release its locks
+before completing. The results of a deadlock are datastore-dependent; usually
+one transaction is forcefully rolled back after some specified timeout interval,
+and an exception is thrown.
+ </para>
+ <para>
+ <indexterm>
+ <primary>
+ transactions
+ </primary>
+ <secondary>
+ datastore
+ </secondary>
+ </indexterm>
+ <indexterm>
+ <primary>
+ datastore transactions
+ </primary>
+ <see>
+ transactions, datastore
+ </see>
+ </indexterm>
+This document will often use the term <emphasis>datastore</emphasis> transaction
+in place of <emphasis>pessimistic</emphasis> transaction. This is to acknowledge
+that some datastores do not support pessimistic semantics, and that the exact
+meaning of a non-optimistic JPA transaction is dependent on the datastore. Most
+of the time, a datastore transaction is equivalent to a pessimistic transaction.
+ </para>
+ <para>
+ <indexterm>
+ <primary>
+ transactions
+ </primary>
+ <secondary>
+ optimistic
+ </secondary>
+ </indexterm>
+ <indexterm>
+ <primary>
+ optimistic transactions
+ </primary>
+ <see>
+ transactions, optimistic
+ </see>
+ </indexterm>
+Optimistic transactions consume less resources than pessimistic/datastore
+transactions, but only at the expense of reliability. Because optimistic
+transactions do not lock datastore records, two transactions might change the
+same persistent information at the same time, and the conflict will not be
+detected until the second transaction attempts to flush or commit. At this time,
+the second transaction will realize that another transaction has concurrently
+modified the same records (usually through a timestamp or versioning system),
+and will throw an appropriate exception. Note that optimistic transactions still
+maintain data integrity; they are simply more likely to fail in heavily
+concurrent situations.
+ </para>
+ <para>
+Despite their drawbacks, optimistic transactions are the best choice for most
+applications. They offer better performance, better scalability, and lower risk
+of hanging due to deadlock.
+ </para>
<note>
- <para>
- OpenJPA uses optimistic semantics by default, but supports both
- optimistic and datastore transactions.
- OpenJPA also offers advanced locking and versioning APIs for
- fine-grained control over database resource allocation and object
- versioning. See <xref linkend="ref_guide_locking"/> and
- <xref linkend="ref_guide_lock_groups"/> of the Reference Guide for
- details on locking. <xref linkend="jpa_overview_meta_version"/>
- of this document covers standard object versioning.
- <!-- ### EJBDOC : link additional strats when available from JPA -->
- </para>
+ <para>
+OpenJPA uses optimistic semantics by default, but supports both optimistic and
+datastore transactions. OpenJPA also offers advanced locking and versioning APIs
+for fine-grained control over database resource allocation and object
+versioning. See <xref linkend="ref_guide_locking"></xref> and
+<xref linkend="ref_guide_lock_groups"></xref> of the Reference Guide for details
+on locking. <xref linkend="jpa_overview_meta_version"></xref>
+of this document covers standard object versioning, while
+<xref linkend="ref_guide_mapping_jpa"/> of the Reference Guide discusses
+additional versioning strategies available in OpenJPA.
+ </para>
</note>
- </section>
- <section id="jpa_overview_trans_ejb3">
- <title>The EntityTransaction Interface</title>
- <indexterm zone="jpa_overview_trans_ejb3">
- <primary>Transaction</primary>
- <seealso>transactions</seealso>
+ </section>
+ <section id="jpa_overview_trans_local">
+ <title>
+ The EntityTransaction Interface
+ </title>
+ <indexterm zone="jpa_overview_trans_local">
+ <primary>
+ Transaction
+ </primary>
+ <seealso>
+ transactions
+ </seealso>
</indexterm>
<mediaobject>
- <imageobject>
-<!-- PNG image data, 193 x 157 (see README) -->
- <imagedata fileref="img/jpa-transaction.png" width="129px"/>
- </imageobject>
+ <imageobject>
+ <!-- PNG image data, 193 x 157 (see README) -->
+ <imagedata fileref="img/jpa-transaction.png" width="129px">
+ </imagedata>
+ </imageobject>
</mediaobject>
<para>
- JPA integrates with your container's <emphasis>managed
- </emphasis> transactions, allowing you to use the container's
- declarative transaction demarcation and its Java Transaction API (JTA)
- implementation for transaction management.
- Outside of a container, though, you must demarcate transactions
- manually through JPA. The <classname>
- EntityTransaction</classname> interface controls unmanaged transactions
- in JPA.
- </para>
- <programlisting format="linespecific">
+JPA integrates with your container's <emphasis>managed</emphasis> transactions,
+allowing you to use the container's declarative transaction demarcation and its
+Java Transaction API (JTA) implementation for transaction management. Outside of
+a container, though, you must demarcate transactions manually through JPA. The
+<classname> EntityTransaction</classname> interface controls unmanaged
+transactions in JPA.
+ </para>
+<programlisting>
public void begin ();
public void commit ();
public void rollback ();
</programlisting>
- <para><indexterm><primary>Transaction</primary><secondary>demarcation</secondary></indexterm><indexterm><primary>transactions</primary><secondary>demarcating</secondary></indexterm><indexterm><primary>Transaction</primary><secondary>begin</secondary></indexterm><indexterm><primary>Transaction</primary><secondary>commit</secondary></indexterm><indexterm><primary>Transaction</primary><secondary>rollback</secondary></indexterm>
- The <methodname>begin</methodname>, <methodname>commit</methodname>,
- and <methodname>rollback</methodname> methods demarcate transaction
- boundaries. The methods should be self-explanatory:
- <methodname>begin</methodname> starts a transaction,
- <methodname>commit</methodname> attempts to commit the transaction's
- changes to the datastore, and <methodname>rollback</methodname>
- aborts the transaction, in which case the datastore is
- "rolled back" to its previous state. JPA
- implementations will automatically roll back transactions if any
- exception is thrown during the commit process.
- </para>
- <para>
- Unless you are using an extended persistence context, committing or
- rolling back also ends the persistence context. All managed entites
- will be detached from the <classname>EntityManager</classname>.
- </para>
- <programlisting format="linespecific">
+ <para>
+ <indexterm>
+ <primary>
+ Transaction
+ </primary>
+ <secondary>
+ demarcation
+ </secondary>
+ </indexterm>
+ <indexterm>
+ <primary>
+ transactions
+ </primary>
+ <secondary>
+ demarcating
+ </secondary>
+ </indexterm>
+ <indexterm>
+ <primary>
+ Transaction
+ </primary>
+ <secondary>
+ begin
+ </secondary>
+ </indexterm>
+ <indexterm>
+ <primary>
+ Transaction
+ </primary>
+ <secondary>
+ commit
+ </secondary>
+ </indexterm>
+ <indexterm>
+ <primary>
+ Transaction
+ </primary>
+ <secondary>
+ rollback
+ </secondary>
+ </indexterm>
+The <methodname>begin</methodname>, <methodname>commit</methodname>, and
+<methodname>rollback</methodname> methods demarcate transaction boundaries. The
+methods should be self-explanatory: <methodname>begin</methodname> starts a
+transaction, <methodname>commit</methodname> attempts to commit the
+transaction's changes to the datastore, and <methodname>rollback</methodname>
+aborts the transaction, in which case the datastore is "rolled back" to its
+previous state. JPA implementations will automatically roll back transactions if
+any exception is thrown during the commit process.
+ </para>
+ <para>
+Unless you are using an extended persistence context, committing or rolling back
+also ends the persistence context. All managed entites will be detached from the
+<classname>EntityManager</classname>.
+ </para>
+<programlisting>
public boolean isActive ();
</programlisting>
- <para><indexterm><primary>Transaction</primary><secondary>isActive</secondary></indexterm>
- Finally, the <methodname>isActive</methodname> method returns
- <literal>true</literal> if the transaction is in progress
- (<methodname>begin</methodname> has been called more recently than
- <methodname>commit</methodname> or
- <methodname>rollback</methodname>), and <literal>false</literal>
- otherwise.
- </para>
+ <para>
+ <indexterm>
+ <primary>
+ Transaction
+ </primary>
+ <secondary>
+ isActive
+ </secondary>
+ </indexterm>
+Finally, the <methodname>isActive</methodname> method returns <literal>true
+</literal> if the transaction is in progress ( <methodname>begin</methodname>
+has been called more recently than <methodname>commit</methodname> or
+<methodname>rollback</methodname> ), and <literal>false</literal> otherwise.
+ </para>
<example id="jpa_overview_trans_group">
- <title>Grouping Operations with Transactions</title>
- <programlisting format="linespecific">
+ <title>
+ Grouping Operations with Transactions
+ </title>
+<programlisting>
public void transferFunds (EntityManager em, User from, User to, double amnt)
{
// note: it would be better practice to move the transaction demarcation
@@ -230,5 +419,5 @@
}
</programlisting>
</example>
- </section>
- </chapter>
+ </section>
+</chapter>