OCILIB (C Driver for Oracle) 3.12.1
transaction.c
00001 /*
00002     +-----------------------------------------------------------------------------------------+
00003     |                                                                                         |
00004     |                               OCILIB - C Driver for Oracle                              |
00005     |                                                                                         |
00006     |                                (C Wrapper for Oracle OCI)                               |
00007     |                                                                                         |
00008     |                              Website : http://www.ocilib.net                            |
00009     |                                                                                         |
00010     |             Copyright (c) 2007-2013 Vincent ROGIER <vince.rogier@ocilib.net>            |
00011     |                                                                                         |
00012     +-----------------------------------------------------------------------------------------+
00013     |                                                                                         |
00014     |             This library is free software; you can redistribute it and/or               |
00015     |             modify it under the terms of the GNU Lesser General Public                  |
00016     |             License as published by the Free Software Foundation; either                |
00017     |             version 2 of the License, or (at your option) any later version.            |
00018     |                                                                                         |
00019     |             This library is distributed in the hope that it will be useful,             |
00020     |             but WITHOUT ANY WARRANTY; without even the implied warranty of              |
00021     |             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU           |
00022     |             Lesser General Public License for more details.                             |
00023     |                                                                                         |
00024     |             You should have received a copy of the GNU Lesser General Public            |
00025     |             License along with this library; if not, write to the Free                  |
00026     |             Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.          |
00027     |                                                                                         |
00028     +-----------------------------------------------------------------------------------------+
00029 */
00030 
00031 /* --------------------------------------------------------------------------------------------- *
00032  * $Id: transaction.c, Vincent Rogier $
00033  * --------------------------------------------------------------------------------------------- */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ********************************************************************************************* *
00038  *                            PUBLIC FUNCTIONS
00039  * ********************************************************************************************* */
00040 
00041 /* --------------------------------------------------------------------------------------------- *
00042  * OCI_TransactionCreate
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 OCI_Transaction * OCI_API OCI_TransactionCreate
00046 (
00047     OCI_Connection *con,
00048     unsigned int    timeout,
00049     unsigned int    mode,
00050     OCI_XID        *pxid
00051 )
00052 {
00053     OCI_Item *item         = NULL;
00054     OCI_Transaction *trans = NULL;
00055     boolean res            = TRUE;
00056 
00057     OCI_CHECK_INITIALIZED(NULL);
00058 
00059     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
00060 
00061     /* create transaction object */
00062 
00063     item = OCI_ListAppend(con->trsns, sizeof(*trans));
00064 
00065     if (item != NULL)
00066     {
00067         trans = (OCI_Transaction *) item->data;
00068 
00069         trans->con     = con;
00070         trans->mode    = mode;
00071         trans->timeout = timeout;
00072         trans->local   = (pxid == NULL);
00073 
00074         /* allocate transaction handle */
00075 
00076         if (res == TRUE)
00077         {
00078             res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) trans->con->env,
00079                                                   (dvoid **) (void *) &trans->htr,
00080                                                   (ub4) OCI_HTYPE_TRANS,
00081                                                   (size_t) 0, (dvoid **) NULL));
00082         }
00083 
00084         /* set XID attribute for global transaction */
00085 
00086         if (pxid != NULL)
00087         {
00088             memcpy(&trans->xid, pxid, sizeof(trans->xid));
00089 
00090             OCI_CALL2
00091             (
00092                 res, con,
00093 
00094                 OCIAttrSet((dvoid *) trans->htr, (ub4) OCI_HTYPE_TRANS,
00095                            (dvoid *) &trans->xid, (ub4) sizeof(trans->xid),
00096                            (ub4) OCI_ATTR_XID, trans->con->err)
00097             )
00098         }
00099     }
00100     else
00101     {
00102        res = FALSE;
00103     }
00104 
00105     /* handle errors */
00106 
00107     if (res == FALSE)
00108     {
00109         OCI_TransactionFree(trans);
00110         trans = NULL;
00111     }
00112 
00113     OCI_RESULT(res);
00114 
00115     return trans;
00116 }
00117 
00118 /* --------------------------------------------------------------------------------------------- *
00119  * OCI_TransactionClose
00120  * --------------------------------------------------------------------------------------------- */
00121 
00122 boolean OCI_TransactionClose
00123 (
00124     OCI_Transaction * trans
00125 )
00126 {
00127     boolean res = TRUE;
00128 
00129     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
00130 
00131     res = OCI_TransactionStop(trans);
00132 
00133     /* close transaction handle */
00134 
00135     if (trans->htr != NULL)
00136     {
00137         OCI_HandleFree((dvoid *) trans->htr, (ub4) OCI_HTYPE_TRANS);
00138     }
00139 
00140     if (trans->con->trs == trans)
00141     {
00142         trans->con->trs = NULL;
00143     }
00144 
00145     return res;
00146 }
00147 
00148 /* --------------------------------------------------------------------------------------------- *
00149  * OCI_TransactionFree
00150  * --------------------------------------------------------------------------------------------- */
00151 
00152 boolean OCI_API OCI_TransactionFree
00153 (
00154     OCI_Transaction * trans
00155 )
00156 {
00157     boolean res = TRUE;
00158 
00159     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
00160 
00161     res = OCI_TransactionClose(trans);
00162 
00163     /* remove transaction from internal list */
00164 
00165     OCI_ListRemove(trans->con->trsns, trans);
00166 
00167     OCI_FREE(trans);
00168 
00169     OCI_RESULT(res);
00170 
00171     return res;
00172 }
00173 
00174 /* --------------------------------------------------------------------------------------------- *
00175  * OCI_TransactionStart
00176  * --------------------------------------------------------------------------------------------- */
00177 
00178 boolean OCI_API OCI_TransactionStart
00179 (
00180     OCI_Transaction * trans
00181 )
00182 {
00183     boolean res = TRUE;
00184 
00185     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
00186 
00187     OCI_CALL2
00188     (
00189         res, trans->con,
00190 
00191         OCITransStart(trans->con->cxt, trans->con->err, (uword) trans->timeout,
00192                       (ub4) trans->mode)
00193     )
00194 
00195     OCI_RESULT(res);
00196 
00197     return res;
00198 }
00199 
00200 /* --------------------------------------------------------------------------------------------- *
00201  * OCI_TransactionStop
00202  * --------------------------------------------------------------------------------------------- */
00203 
00204 boolean OCI_API OCI_TransactionStop
00205 (
00206     OCI_Transaction * trans
00207 )
00208 {
00209     boolean res = TRUE;
00210 
00211     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
00212 
00213     /* commit or rollback upon auto commit mode */
00214 
00215     if (trans->con->autocom == TRUE)
00216     {
00217         res = OCI_Commit(trans->con);
00218     }
00219     else
00220     {
00221         res = OCI_Rollback(trans->con);
00222     }
00223 
00224     /* detach global transaction */
00225 
00226     if (trans->local == FALSE)
00227     {
00228         OCI_CALL2
00229         (
00230             res, trans->con,
00231 
00232             OCITransDetach(trans->con->cxt, trans->con->err, (ub4) OCI_DEFAULT)
00233         )
00234     }
00235 
00236     OCI_RESULT(res);
00237 
00238     return res;
00239 }
00240 
00241 /* --------------------------------------------------------------------------------------------- *
00242  * OCI_TransactionResume
00243  * --------------------------------------------------------------------------------------------- */
00244 
00245 boolean OCI_API OCI_TransactionResume
00246 (
00247     OCI_Transaction * trans
00248 )
00249 {
00250     boolean res = TRUE;
00251 
00252     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
00253 
00254     OCI_CALL2
00255     (
00256         res, trans->con,
00257 
00258         OCITransStart(trans->con->cxt, trans->con->err,
00259                       (uword) trans->timeout, (ub4) OCI_TRANS_RESUME)
00260     )
00261 
00262     OCI_RESULT(res);
00263 
00264     return res;
00265 }
00266 
00267 /* --------------------------------------------------------------------------------------------- *
00268  * OCI_TransactionPrepare
00269  * --------------------------------------------------------------------------------------------- */
00270 
00271 boolean OCI_API OCI_TransactionPrepare
00272 (
00273     OCI_Transaction * trans
00274 )
00275 {
00276     boolean res = TRUE;
00277 
00278     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
00279 
00280     OCI_CALL2
00281     (
00282         res, trans->con,
00283 
00284         OCITransPrepare(trans->con->cxt, trans->con->err, (ub4) OCI_DEFAULT)
00285     )
00286 
00287     OCI_RESULT(res);
00288 
00289     return res;
00290 }
00291 
00292 /* --------------------------------------------------------------------------------------------- *
00293  * OCI_TransactionForget
00294  * --------------------------------------------------------------------------------------------- */
00295 
00296 boolean OCI_API OCI_TransactionForget
00297 (
00298     OCI_Transaction * trans
00299 )
00300 {
00301     boolean res = TRUE;
00302 
00303     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
00304 
00305     OCI_CALL2
00306     (
00307         res, trans->con,
00308 
00309         OCITransForget(trans->con->cxt, trans->con->err, (ub4) OCI_DEFAULT)
00310     )
00311 
00312     OCI_RESULT(res);
00313 
00314     return res;
00315 }
00316 
00317 /* --------------------------------------------------------------------------------------------- *
00318  * OCI_TransactionGetMode
00319  * --------------------------------------------------------------------------------------------- */
00320 
00321 unsigned int OCI_API OCI_TransactionGetMode
00322 (
00323     OCI_Transaction * trans
00324 )
00325 {
00326     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, OCI_UNKNOWN);
00327 
00328     OCI_RESULT(TRUE);
00329 
00330     return trans->mode;
00331 }
00332 
00333 /* --------------------------------------------------------------------------------------------- *
00334  * OCI_TransactionGetTimeout
00335  * --------------------------------------------------------------------------------------------- */
00336 
00337 unsigned int OCI_API OCI_TransactionGetTimeout
00338 (
00339     OCI_Transaction * trans
00340 )
00341 {
00342     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, 0);
00343 
00344     OCI_RESULT(TRUE);
00345 
00346     return trans->timeout;
00347 }