001: /*
002: * Created on Feb 22, 2004
003: */
004: package net.sourceforge.orbroker;
005:
006: import java.sql.Connection;
007: import java.sql.SQLException;
008: import java.sql.Savepoint;
009: import java.util.Collection;
010:
011: /**
012: * Executable connection.
013: *
014: * @author Nils Kilden-Pedersen
015: * @see net.sourceforge.orbroker.Broker#startTransaction()
016: * @see net.sourceforge.orbroker.Broker#startTransaction(int)
017: */
018: abstract class ExecutableConnection extends QueryableConnection {
019:
020: private static final int[] EMPTY_COUNT = new int[0];
021:
022: ExecutableConnection(Broker broker, Connection connection) {
023: super (broker, connection);
024: }
025:
026: ExecutableConnection(Broker broker, Integer isolationLevel)
027: throws BrokerException {
028: super (broker, isolationLevel);
029: }
030:
031: protected Statement getStatement(String statementID)
032: throws BrokerException {
033: markTransactionStarted();
034: return super .getStatement(statementID);
035: }
036:
037: protected abstract void markTransactionStarted();
038:
039: /**
040: * Execute statement. This is used for statements such as
041: * <ul>
042: * <li>UPDATE</li>
043: * <li>DELETE</li>
044: * <li>INSERT</li>
045: * <li>CALL</li>
046: * </ul>
047: *
048: * @param statementID Statement id
049: * @return number of records affected.
050: * @throws BrokerException
051: * @throws ConstraintException
052: * @throws DeadlockException
053: */
054: public int execute(String statementID) throws BrokerException,
055: ConstraintException, DeadlockException {
056: Statement stm = getStatement(statementID);
057: try {
058: return stm.executeUpdate(getActiveConnection(),
059: getConnectionContext());
060: } catch (SQLException e) {
061: if (retryFailedStatement(e)) {
062: return execute(statementID);
063: }
064: throwException(e);
065: }
066: // Not going to happen, but necessary for compiler
067: return 0;
068: }
069:
070: /**
071: * Execute a collection of parameters as a batch.
072: *
073: * @param statementID Statement id
074: * @param batchParameterName
075: * The parameter name that will be repeated
076: * @param batchParameters
077: * The collection of batch parameter objects
078: * @return Total records affected, or a negative number if unknown
079: * @throws BrokerException
080: * @throws ConstraintException
081: * @throws DeadlockException
082: */
083: public int executeBatch(String statementID,
084: String batchParameterName, Collection batchParameters)
085: throws BrokerException, ConstraintException,
086: DeadlockException {
087:
088: int[] counts = executeBatch(statementID, batchParameterName,
089: batchParameters.toArray());
090: int totalCount = 0;
091: for (int i = 0; i < counts.length; i++) {
092: if (counts[i] < 0) {
093: return counts[i];
094: }
095: totalCount += counts[i];
096: }
097: return totalCount;
098:
099: }
100:
101: /**
102: * Execute an array of parameters as a batch.
103: *
104: * @param statementID Statement id
105: * @param batchParameterName
106: * The parameter name that will be repeated
107: * @param batchParameters
108: * The array of batch objects
109: * @return Total records affected per parameter, or a negative number if unknown
110: * @throws BrokerException
111: * @throws ConstraintException
112: * @throws DeadlockException
113: */
114: public int[] executeBatch(String statementID,
115: String batchParameterName, Object[] batchParameters)
116: throws BrokerException, ConstraintException,
117: DeadlockException {
118:
119: if (batchParameters == null || batchParameters.length == 0) {
120: return EMPTY_COUNT;
121: }
122:
123: if (!supportsBatch()) {
124: throw new BrokerException(
125: "Batch execution is not supported by driver");
126: }
127:
128: int[] totalCount = EMPTY_COUNT;
129: Statement stm = getStatement(statementID);
130: try {
131: totalCount = stm.executeBatch(getActiveConnection(),
132: getConnectionContext(), batchParameterName,
133: batchParameters);
134: } catch (SQLException e) {
135: if (retryFailedStatement(e)) {
136: return executeBatch(statementID, batchParameterName,
137: batchParameters);
138: }
139: throwException(e);
140: }
141: return totalCount;
142: }
143:
144: /**
145: * Release savepoint.
146: * @param savepoint Savepoint
147: * @see Connection#releaseSavepoint(java.sql.Savepoint)
148: */
149: public void releaseSavepoint(Savepoint savepoint) {
150: try {
151: getActiveConnection().releaseSavepoint(savepoint);
152: } catch (SQLException e) {
153: throwException(e);
154: }
155: }
156:
157: /**
158: * Roll back to savepoint.
159: * @param savepoint Savepoint
160: * @see Connection#rollback(java.sql.Savepoint)
161: */
162: public void rollback(Savepoint savepoint) {
163: try {
164: getActiveConnection().rollback(savepoint);
165: } catch (SQLException e) {
166: throwException(e);
167: }
168: }
169:
170: /**
171: * Set savepoint.
172: * @return savepoint
173: * @see Connection#setSavepoint()
174: */
175: public Savepoint setSavepoint() {
176: return setSavepoint(null);
177: }
178:
179: /**
180: * Set named savepoint.
181: * @param name Savepoint name
182: * @return savepoint
183: * @see Connection#setSavepoint(String)
184: * */
185: public Savepoint setSavepoint(String name) {
186: Savepoint sp = null;
187: try {
188: if (name != null) {
189: sp = getActiveConnection().setSavepoint(name);
190: } else {
191: sp = getActiveConnection().setSavepoint();
192: }
193: } catch (SQLException e) {
194: if (retryFailedStatement(e)) {
195: return setSavepoint(name);
196: }
197: throwException(e);
198: }
199: return sp;
200: }
201: }
|