How to Transaction Management » History » Version 12
Henning Blohm, 17.09.2012 13:35
1 | 10 | Henning Blohm | h1. Transaction management in Z2 |
---|---|---|---|
2 | 3 | Henning Blohm | |
3 | 11 | Henning Blohm | (work in progress) |
4 | |||
5 | 12 | Henning Blohm | This page provides some hints and pointers on how to implement transaction management for modular applications on Z2. There are a few utilities provided with Z2 that may help you implement transaction handling for the simple cases, and this site provides examples that show how to address the more complicated cases. |
6 | |||
7 | Everything below is describing use and enabling of a Java Transaction API ("JTA":http://de.wikipedia.org/wiki/Java_Transaction_API) based approach to transaction management. |
||
8 | |||
9 | Note that there is nothing in Z2 that prevents you from using a previously implemented Web application-local based transaction management. The information on this page is most useful, if you have a modular application that requires transaction management also on a service level. |
||
10 | |||
11 | The following aspects will be discussed: |
||
12 | |||
13 | * The built-in, non-XA JTA implementation of Z2 |
||
14 | * Controlling transactions in code |
||
15 | * Using Datasource components |
||
16 | * Using Hibernate JPA |
||
17 | * Using a full-blown transaction manager |
||
18 | * Integration with Jetty |
||
19 | * Integration with Spring |
||
20 | |||
21 | h2. The built-in, non-XA JTA implementation of Z2 (com.zfabrik.jta) |
||
22 | |||
23 | The "z2-base.base":http://redmine.z2-environment.net/projects/z2-base/repository/base repository contains the JTA 1.1 API and an implementation of it in the module *com.zfabrik.jta*. |
||
24 | |||
25 | *Note*: This is not an XA-capable transaction manager. This implementation provides no atomic transaction control for more than one transactional resource! |
||
26 | |||
27 | But, this implementation is still most useful, if you do not need distributed transactions (which is preferable in most cases) and still want to benefit from the JTA API as an integration point. |
||
28 | |||
29 | Technically the implementation relies on Z2's _Unit of Work_ abstraction (see "Unit of Work and transaction management":http://www.z2-environment.eu/v21doc#Unit%20of%20Work%20and%20transaction%20management). As long as all interactions with an application are issued from a Web application this is completely transparent. When invoking code from other entry points, e.g. from an embedded scheduling service for example, this has an impact that will be discussed below. |
||
30 | |||
31 | The "TransactionManager":http://docs.oracle.com/javaee/6/api/javax/transaction/TransactionManager.html interface, as well as the "UserTransaction":http://docs.oracle.com/javaee/6/api/javax/transaction/UserTransaction.html interface are available from the component *com.zfabrik.jta/userTransaction* and can be looked up via the Z2 core API |
||
32 | |||
33 | <pre><code class="java">IComponentsLookup.INSTANCE.lookup("com.zfabrik.jta/userTransaction",TransactionManager.class)</code></pre> |
||
34 | |||
35 | or via JNDI as |
||
36 | |||
37 | <pre><code class="java">new InitialContext().lookup("components:com.zfabrik.jta/userTransaction?type=javax.transaction.TransactionManager")</code></pre> |
||
38 | |||
39 | and similarly for the UserTransaction interface. |
||
40 | |||
41 | This simple approach to JTA has been used in the samples [[Sample-hibernate-basic-TBD]] and [[Sample-spring-hibernate-TBD]]. |
||
42 | |||
43 | h2. Controlling transactions in code |
||
44 | |||
45 | Now that you have a JTA implementation you need to indicate where transactions start and end. The most basic (and most understandable) approach to that is to use the UserTransaction interface. Typically in a flow like this: |
||
46 | |||
47 | <pre><code class="java"> |
||
48 | UserTransaction ut = (UserTransaction) new InitialContext().lookup( JNDI_NAME ); |
||
49 | ut.begin(); |
||
50 | try { |
||
51 | // do some work |
||
52 | } catch (Exception e) { |
||
53 | logger.log(Level.WARNING,"Error at transaction boundary. Setting transaction to rollbackonly",e); |
||
54 | ut.setRollbackOnly(); |
||
55 | throw e; |
||
56 | } finally { |
||
57 | if (ut.getStatus()==Status.STATUS_ACTIVE) { |
||
58 | ut.commit(); |
||
59 | } else { |
||
60 | ut.rollback(); |
||
61 | } |
||
62 | } |
||
63 | </code></pre> |
||
64 | |||
65 | The constant *JNDI_NAME* is intentionally left undefined here. If you use *com.zfabrik.jta* you may use the name specified above. If the code above is part of a Servlet Filter that is supposed to begin and end transactions on the boundaries of a Web request, you can use the standard name "java:comp/UserTransaction" given you integrated the transaction management with Jetty (see below). |
||
66 | |||
67 | Now that we looked at it, fortunately you do not need to implement this yourself. Here are some alternatives: |
||
68 | |||
69 | * Use "TransactionUtil":http://redmine.z2-environment.net/projects/z2-base/repository/base/revisions/master/entry/com.zfabrik.jta/java/src.api/com/zfabrik/tx/TransactionUtil.java from *com.zfabrik.jta* that implements just the flow above. |
||
70 | * Use Spring's transaction management support including annotation based transaction demarcation, as for example in [[Sample-spring-hibernate-TBD]] and [[Sample-jta-spring]] (see also [[How to Spring]]). |
||
71 | * Use any of the many "Transaction Filter" implementations out there. |
||
72 | |||
73 | h2. Using DataSource components |
||
74 | |||
75 | A JDBC data source wraps JDBC connections, i.e. actual database connections, for re-use along the control flow. |
||
76 | |||
77 | When accessing the same database multiple times within one transaction, you want to make sure you re-use the same (underlying) JDBC connection. That is, you may (typically) not have more than one (underlying) JDBC connection to the very same database that share the same (non-distributed) transaction. Hence the typical implementation associates a JDBC connection to a database with the transaction that is associated with the current thread of execution. Obviously there is a strong tie between the management of database connections and the transaction management system. JDBC data sources provide the accessor interface to database connections. You may hold of to a data source and ask it for a connection when needed, but you should not hold on to the actual connection object between invocations of your service interface. |
||
78 | |||
79 | Z2 offers a built-in DataSource component type. This is useful, if you use *com.zfabrik.jta*. If you use another transaction management system, you should most likely use another data source implementation. See for example [[Sample-jta-plain]]. |
||
80 | |||
81 | When using the built-in data source, you can look up the "DataSource":http://docs.oracle.com/javase/6/docs/api/javax/sql/DataSource.html interface via a component lookup, e.g. via JNDI like this: |
||
82 | |||
83 | <pre><code class="java">(DataSource) new InitialContext().lookup(COMPONENT_NAME?type=javax.sql.DataSource)</code></pre> |
||
84 | |||
85 | where *COMPONENT_NAME* has to be substituted by the real name of the data source component. |
||
86 | |||
87 | The built-in data sources have been used for example in [[Sample-hibernate-basic-TBD]] and [[Sample-spring-hibernate-TBD]]. |
||
88 | |||
89 | |||
90 | h2. Using Hibernate and JPA |
||
91 | |||
92 | Now you have a JTA implementation in place as well as data sources defined, |
||
93 | |||
94 | |||
95 | |||
96 | What data source |
||
97 | |||
98 | |||
99 | |||
100 | |||
101 | |||
102 | |||
103 | |||
104 | |||
105 | |||
106 | |||
107 | If you have implemented transaction management locally to a Web application already using Hibernate Sessions or the simple transaction management provided by the Spring framework and you do not intent to have other entry points to your application scenario you may skip this page. |
||
108 | |||
109 | |||
110 | (work in progress) |
||
111 | |||
112 | |||
113 | |||
114 | 11 | Henning Blohm | Alternatives - mini JTA, full JTA. |
115 | Integration points: Jetty, Hibernate, Spring |
||
116 | |||
117 | Explain transaction util. |
||
118 | |||
119 | ------------ |
||
120 | |||
121 | |||
122 | 3 | Henning Blohm | This Wiki is about how to integrate a full-blown transaction manager into Z2. We only consider Atomikos for now, hoping other TMs can be used similarly. |
123 | |||
124 | 4 | Henning Blohm | Note that the z2-base.base repository contains the JTA 1.1 API and an implementation of it in the module *com.zfabrik.jta*. That is however not a real, full-featured transaction manager - rather just a pseudo-distributed transaction management implementation. There is no 2-phase-commit handling. |
125 | |||
126 | It is still extremely useful for 90% case where global, distributed transactions are unnecessary overkill. |
||
127 | 3 | Henning Blohm | |
128 | At times however, you may require a real TM and even if you dont and want to use Atomikos with non-XA data sources, in which case it behaves similarly to *com.zfabrik.jta*, here is how it's done. |
||
129 | |||
130 | There are two samples related to this page: |
||
131 | |||
132 | 8 | Henning Blohm | * *z2-samples.jta-plain*: A sample scenario with just z2-base and Atomikos and no further trickery. This samples explains best what is needed to get going. See also [[Sample_jta_plain]]. |
133 | 7 | Henning Blohm | * *z2-samples.jta-spring*: A sample scenario built on z2-base, z2-addons.spring, and Atomikos. This is the more advanced, Spring-minded case. The underlying mechanics may be harder to grasp though. See also [[samples_jta_spring]]. |
134 | 3 | Henning Blohm | |
135 | Please consult [[How_to_Run_a_Sample]] on how to run these samples. |
||
136 | 6 | Henning Blohm | |
137 | h2. References |
||
138 | |||
139 | * [[How_to_Run_a_Sample]] |
||
140 | * [[How_to_Spring]] |