1 /*
2 * Copyright 2003 - 2013 The eFaps Team
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * Revision: $Rev$
17 * Last Changed: $Date$
18 * Last Changed By: $Author$
19 */
20
21 package org.efaps.db.transaction;
22
23 import java.sql.Connection;
24 import java.sql.SQLException;
25
26 import javax.transaction.xa.XAException;
27 import javax.transaction.xa.Xid;
28
29 import org.efaps.db.Context;
30 import org.efaps.util.EFapsException;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 /**
35 * The class implements the XAResource interface for SQL connections.
36 *
37 * @author The eFaps Team
38 * @version $Id$
39 */
40 public class ConnectionResource
41 extends AbstractResource
42 {
43 /**
44 * Logging instance used in this class.
45 */
46 private static final Logger LOG = LoggerFactory.getLogger(ConnectionResource.class);
47
48 /**
49 * Stores the SQL connection of this connection resource.
50 */
51 private Connection connection = null;
52
53 /**
54 * @param _connection SQL connection
55 * @throws SQLException if auto commit could not be set to <i>false</i>
56 */
57 public ConnectionResource(final Connection _connection)
58 throws SQLException
59 {
60 this.connection = _connection;
61 this.connection.setAutoCommit(false);
62 }
63
64 /**
65 * This is the getter method for instance variable {@link #connection}.
66 *
67 * @return value of instance variable {@link #connection}
68 * @see #connection
69 */
70 public final Connection getConnection()
71 {
72 return this.connection;
73 }
74
75 /**
76 * Frees the resource and gives this connection resource back to the
77 * context object.
78 */
79 @Override
80 protected void freeResource()
81 {
82 try {
83 ConnectionResource.LOG.debug("free Resource: {}", this);
84 Context.getThreadContext().returnConnectionResource(this);
85 } catch (final EFapsException e) {
86 ConnectionResource.LOG.error("EFapsException", e);
87 }
88 }
89
90 /**
91 * Ask the resource manager to prepare for a transaction commit of the
92 * transaction specified in xid (used for 2-phase commits).
93 * @param _xid Xid
94 * @return 0
95 */
96 public int prepare(final Xid _xid)
97 {
98 ConnectionResource.LOG.trace("prepare (xid = {})", _xid);
99 return 0;
100 }
101
102 /**
103 * Commits the global transaction specified by xid.
104 * @param _xid Xid
105 * @param _onePhase one phase
106 * @throws XAException on error
107 */
108 public void commit(final Xid _xid,
109 final boolean _onePhase)
110 throws XAException
111 {
112 ConnectionResource.LOG.trace("commit (xid = {}, one phase = {})", _xid, _onePhase);
113 try {
114 if (this.connection != null) {
115 this.connection.commit();
116 }
117 } catch (final SQLException e) {
118 final XAException xa = new XAException(XAException.XA_RBCOMMFAIL);
119 xa.initCause(e);
120 throw xa;
121 } finally {
122 try {
123 if (this.connection != null) {
124 this.connection.close();
125 this.connection = null;
126 }
127 } catch (final SQLException e) {
128 ConnectionResource.LOG.error("SQLException", e);
129 }
130 }
131 }
132
133 /**
134 * Informs the resource manager to roll back work done on behalf of a
135 * transaction branch.
136 * @param _xid Xid
137 * @throws XAException on error
138 */
139 public void rollback(final Xid _xid)
140 throws XAException
141 {
142 ConnectionResource.LOG.trace("rollback (xid = {})", _xid);
143 try {
144 if (this.connection != null) {
145 this.connection.rollback();
146 }
147 } catch (final SQLException e) {
148 final XAException xa = new XAException(XAException.XA_RBCOMMFAIL);
149 xa.initCause(e);
150 throw xa;
151 } finally {
152 try {
153 if (this.connection != null) {
154 this.connection.close();
155 this.connection = null;
156 }
157 } catch (final SQLException e) {
158 ConnectionResource.LOG.error("SQLException", e);
159 }
160 }
161 }
162
163 /**
164 * Tells the resource manager to forget about a heuristically completed
165 * transaction branch.
166 * @param _xid Xid
167 */
168 public void forget(final Xid _xid)
169 {
170 ConnectionResource.LOG.trace("forget (xid = {})", _xid);
171 }
172
173 /**
174 * Obtains the current transaction timeout value set for this XAResource
175 * instance.
176 * @return 0
177 */
178 public int getTransactionTimeout()
179 {
180 ConnectionResource.LOG.trace("getTransactionTimeout");
181 return 0;
182 }
183
184 /**
185 * Obtains a list of prepared transaction branches from a resource manager.
186 * @param _flag flag
187 * @return null
188 */
189 public Xid[] recover(final int _flag)
190 {
191 ConnectionResource.LOG.trace("recover (flag = {})", _flag);
192 return null;
193 }
194
195 /**
196 * Sets the current transaction timeout value for this XAResource instance.
197 * From this implementation ignored.
198 *
199 * @param _seconds time out in seconds
200 * @return always <i>true</i>
201 */
202 public boolean setTransactionTimeout(final int _seconds)
203 {
204 ConnectionResource.LOG.debug("setTransactionTimout");
205 return true;
206 }
207 }