Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

xa_db.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1998-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: xa_db.c,v 12.4 2005/10/20 18:57:16 bostic Exp $
00008  */
00009 
00010 #include "db_config.h"
00011 
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014 #endif
00015 
00016 #include "db_int.h"
00017 #include "dbinc/txn.h"
00018 
00019 static int __xa_close __P((DB *, u_int32_t));
00020 static int __xa_cursor __P((DB *, DB_TXN *, DBC **, u_int32_t));
00021 static int __xa_del __P((DB *, DB_TXN *, DBT *, u_int32_t));
00022 static int __xa_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
00023 static int __xa_open __P((DB *, DB_TXN *,
00024             const char *, const char *, DBTYPE, u_int32_t, int));
00025 static int __xa_put __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
00026 static int __xa_set_txn __P((DB *, DB_TXN **, int));
00027 static int __xa_truncate __P((DB *, DB_TXN *, u_int32_t *, u_int32_t));
00028 
00029 typedef struct __xa_methods {
00030         int (*close) __P((DB *, u_int32_t));
00031         int (*cursor) __P((DB *, DB_TXN *, DBC **, u_int32_t));
00032         int (*del) __P((DB *, DB_TXN *, DBT *, u_int32_t));
00033         int (*get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
00034         int (*open) __P((DB *, DB_TXN *,
00035             const char *, const char *, DBTYPE, u_int32_t, int));
00036         int (*put) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
00037         int (*truncate) __P((DB *, DB_TXN *, u_int32_t *, u_int32_t));
00038 } XA_METHODS;
00039 
00040 /*
00041  * __xa_set_txn --
00042  *      Find a transaction handle.
00043  */
00044 static int
00045 __xa_set_txn(dbp, txnpp, no_xa_txn)
00046         DB *dbp;
00047         DB_TXN **txnpp;
00048         int no_xa_txn;
00049 {
00050         DB_ENV *dbenv;
00051         int ret;
00052 
00053         dbenv = dbp->dbenv;
00054 
00055         /*
00056          * It doesn't make sense for a server to specify a DB_TXN handle.
00057          * As the server can't know if other operations it has done have
00058          * committed/aborted, it can self-deadlock.  If the server wants
00059          * other transactions, it can open other DB handles and use them.
00060          * Disallow specified DB_TXN handles.
00061          */
00062         if (*txnpp != NULL) {
00063                 __db_err(dbenv,
00064     "transaction handles should not be directly specified to XA interfaces");
00065                 return (EINVAL);
00066         }
00067 
00068         /* See if the TM has declared a transaction. */
00069         if ((ret = __xa_get_txn(dbenv, txnpp, 0)) != 0)
00070                 return (ret);
00071         if ((*txnpp)->txnid != TXN_INVALID)
00072                 return (0);
00073 
00074         /*
00075          * We may be opening databases in the server initialization routine.
00076          * In that case, it's reasonable not to have an XA transaction.  It's
00077          * also reasonable to open a database as part of an XA transaction,
00078          * allow both.
00079          */
00080         if (no_xa_txn) {
00081                 *txnpp = NULL;
00082                 return (0);
00083         }
00084 
00085         __db_err(dbenv, "no XA transaction declared");
00086         return (EINVAL);
00087 }
00088 
00089 /*
00090  * __db_xa_create --
00091  *      DB XA constructor.
00092  *
00093  * PUBLIC: int __db_xa_create __P((DB *));
00094  */
00095 int
00096 __db_xa_create(dbp)
00097         DB *dbp;
00098 {
00099         XA_METHODS *xam;
00100         int ret;
00101 
00102         /*
00103          * Allocate the XA internal structure, and wrap the open and close
00104          * calls.
00105          */
00106         if ((ret = __os_calloc(dbp->dbenv, 1, sizeof(XA_METHODS), &xam)) != 0)
00107                 return (ret);
00108 
00109         dbp->xa_internal = xam;
00110         xam->open = dbp->open;
00111         dbp->open = __xa_open;
00112         xam->close = dbp->close;
00113         dbp->close = __xa_close;
00114 
00115         return (0);
00116 }
00117 
00118 /*
00119  * __xa_open --
00120  *      XA open wrapper.
00121  */
00122 static int
00123 __xa_open(dbp, txn, name, subdb, type, flags, mode)
00124         DB *dbp;
00125         DB_TXN *txn;
00126         const char *name, *subdb;
00127         DBTYPE type;
00128         u_int32_t flags;
00129         int mode;
00130 {
00131         XA_METHODS *xam;
00132         int ret;
00133 
00134         xam = (XA_METHODS *)dbp->xa_internal;
00135 
00136         if ((ret =
00137             __xa_set_txn(dbp, &txn, LF_ISSET(DB_AUTO_COMMIT) ? 1 : 0)) != 0)
00138                 return (ret);
00139         if ((ret = xam->open(dbp, txn, name, subdb, type, flags, mode)) != 0)
00140                 return (ret);
00141 
00142         /* Wrap any DB handle method that takes a TXN ID as an argument. */
00143         xam->cursor = dbp->cursor;
00144         xam->del = dbp->del;
00145         xam->get = dbp->get;
00146         xam->put = dbp->put;
00147         xam->truncate = dbp->truncate;
00148         dbp->cursor = __xa_cursor;
00149         dbp->del = __xa_del;
00150         dbp->get = __xa_get;
00151         dbp->put = __xa_put;
00152         dbp->truncate = __xa_truncate;
00153 
00154         return (0);
00155 }
00156 
00157 static int
00158 __xa_cursor(dbp, txn, dbcp, flags)
00159         DB *dbp;
00160         DB_TXN *txn;
00161         DBC **dbcp;
00162         u_int32_t flags;
00163 {
00164         int ret;
00165 
00166         if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0)
00167                 return (ret);
00168         return (((XA_METHODS *)
00169             dbp->xa_internal)->cursor(dbp, txn, dbcp, flags));
00170 }
00171 
00172 static int
00173 __xa_del(dbp, txn, key, flags)
00174         DB *dbp;
00175         DB_TXN *txn;
00176         DBT *key;
00177         u_int32_t flags;
00178 {
00179         int ret;
00180 
00181         if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0)
00182                 return (ret);
00183         return (((XA_METHODS *)dbp->xa_internal)->del(dbp, txn, key, flags));
00184 }
00185 
00186 static int
00187 __xa_close(dbp, flags)
00188         DB *dbp;
00189         u_int32_t flags;
00190 {
00191         int (*real_close) __P((DB *, u_int32_t));
00192 
00193         real_close = ((XA_METHODS *)dbp->xa_internal)->close;
00194 
00195         __os_free(dbp->dbenv, dbp->xa_internal);
00196         dbp->xa_internal = NULL;
00197 
00198         return (real_close(dbp, flags));
00199 }
00200 
00201 static int
00202 __xa_get(dbp, txn, key, data, flags)
00203         DB *dbp;
00204         DB_TXN *txn;
00205         DBT *key, *data;
00206         u_int32_t flags;
00207 {
00208         int ret;
00209 
00210         if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0)
00211                 return (ret);
00212         return (((XA_METHODS *)
00213             dbp->xa_internal)->get(dbp, txn, key, data, flags));
00214 }
00215 
00216 static int
00217 __xa_put(dbp, txn, key, data, flags)
00218         DB *dbp;
00219         DB_TXN *txn;
00220         DBT *key, *data;
00221         u_int32_t flags;
00222 {
00223         int ret;
00224 
00225         if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0)
00226                 return (ret);
00227         return (((XA_METHODS *)
00228             dbp->xa_internal)->put(dbp, txn, key, data, flags));
00229 }
00230 
00231 static int
00232 __xa_truncate(dbp, txn, countp, flags)
00233         DB *dbp;
00234         DB_TXN *txn;
00235         u_int32_t *countp, flags;
00236 {
00237         int ret;
00238 
00239         if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0)
00240                 return (ret);
00241         return (((XA_METHODS *)
00242             dbp->xa_internal)->truncate(dbp, txn, countp, flags));
00243 }

Generated on Sun Dec 25 12:14:57 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2