001: /*
002: * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
003: * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
004: */
005:
006: package com.sun.portal.search.db;
007:
008: import com.sleepycat.db.*;
009: import com.sun.portal.search.util.*;
010: import com.sun.portal.search.rdm.*;
011: import com.sun.portal.log.common.PortalLogger;
012:
013: import java.io.*;
014: import java.util.logging.Logger;
015: import java.util.logging.Level;
016:
017: /**
018: * AutoCommitDb is a BDB db wrapper that creates auto transactions when
019: * called with no existing transaction. This ensures db safety in
020: * a multi-threaded environment since BDB can not recover from
021: * deadlocks correctly without transactions.
022: */
023: class AutoCommitDb {
024:
025: final static int AutoCommitDb_DB_TYPE = Db.DB_BTREE;
026: final static int AutoCommitDb_DBT_METHOD = Db.DB_DBT_MALLOC; // XXX
027:
028: DbEnv dbenv;
029: Db db;
030: String location;
031:
032: public void open(String location, int flags, int mode, DbEnv env)
033: throws RDMException {
034: try {
035: // NB: BDB resolves paths relative to dbhome
036: dbenv = env;
037: db = new Db(dbenv, 0);
038: db.open(location, null, AutoCommitDb_DB_TYPE, flags, mode);
039: this .location = location;
040: } catch (FileNotFoundException e) {
041: throw new RDMException(e.getMessage());
042: } catch (DbException dbe) {
043: throw new RDMException(dbe);
044: }
045: }
046:
047: public void close() throws RDMException {
048: try {
049: db.close(0);
050: } catch (DbException dbe) {
051: throw new RDMException(dbe);
052: }
053: }
054:
055: boolean check(Dbt key, RDMTransaction tid) throws RDMException {
056: int rcode = fetch(key, new Dbt(), 0, tid);
057: return rcode == 0;
058: }
059:
060: int fetch(Dbt key, Dbt data, int flags, RDMTransaction t)
061: throws RDMException {
062: int rcode = 0;
063: try {
064: if (t != null)
065: rcode = db.get((DbTxn) t.getNativeTxn(), key, data,
066: flags); // XXX should probably use flags | DIRTY_READ
067: else {
068: for (;;) {
069: try {
070: rcode = db.get(null, key, data, flags); // No txn for simple read
071: } catch (DbDeadlockException e) {
072: // Yes, this can happen, even without transactions
073: SearchLogger.getLogger().log(Level.FINE,
074: "PSSH_CSPSB0001");
075: continue;
076: }
077: break;
078: }
079: }
080: } catch (DbDeadlockException dbd) {
081: SearchLogger.getLogger().log(Level.FINE, "PSSH_CSPSB0002");
082: throw new RDMDeadlockException(dbd);
083: } catch (DbException dbe) {
084: SearchLogger.getLogger().log(Level.FINE, "PSSH_CSPSB0003");
085: throw new RDMException(dbe);
086: }
087: return rcode;
088: }
089:
090: void store(Dbt key, Dbt data, int flags, RDMTransaction t)
091: throws RDMException {
092: try {
093: if (t != null)
094: db.put((DbTxn) t.getNativeTxn(), key, data, flags);
095: else {
096: for (;;) {
097: DbTxn tx = null;
098: try {
099: tx = dbenv.txn_begin(null, 0);
100: db.put(tx, key, data, flags);
101: tx.commit(0);
102: tx = null;
103: } catch (DbDeadlockException e) {
104: SearchLogger.getLogger().log(Level.FINE,
105: "PSSH_CSPSB0001");
106: continue;
107: } finally {
108: if (tx != null) {
109: SearchLogger.getLogger().log(Level.FINE,
110: "PSSH_CSPSB0004");
111: tx.abort();
112: }
113: }
114: break;
115: }
116: }
117: } catch (DbDeadlockException dbd) {
118: SearchLogger.getLogger().log(Level.FINE, "PSSH_CSPSB0002");
119: throw new RDMDeadlockException(dbd);
120: } catch (DbException dbe) {
121: SearchLogger.getLogger().log(Level.FINE, "PSSH_CSPSB0003");
122: throw new RDMException(dbe);
123: }
124: }
125:
126: void delete(Dbt key, int flags, RDMTransaction t)
127: throws RDMException {
128: try {
129: if (t != null)
130: db.del((DbTxn) t.getNativeTxn(), key, flags);
131: else {
132: for (;;) {
133: DbTxn tx = null;
134: try {
135: tx = dbenv.txn_begin(null, 0);
136: db.del(tx, key, flags);
137: tx.commit(0);
138: tx = null;
139: } catch (DbDeadlockException e) {
140: SearchLogger.getLogger().log(Level.FINE,
141: "PSSH_CSPSB0001");
142: continue;
143: } finally {
144: if (tx != null) {
145: SearchLogger.getLogger().log(Level.FINE,
146: "PSSH_CSPSB0004");
147: tx.abort();
148: }
149: }
150: break;
151: }
152: }
153: } catch (DbDeadlockException dbd) {
154: SearchLogger.getLogger().log(Level.FINE, "PSSH_CSPSB0002");
155: throw new RDMDeadlockException(dbd);
156: } catch (DbException dbe) {
157: SearchLogger.getLogger().log(Level.FINE, "PSSH_CSPSB0003");
158: throw new RDMException(dbe);
159: }
160: }
161:
162: /*public DbCursor cursor(RDMTransaction t, int flags) throws RDMException {
163: try {
164: return db.cursor((DbTxn)t.getNativeTxn(), flags);
165: }
166: catch (DbDeadlockException dbd) {
167: SearchLogger.getLogger().log(Level.FINE, "PSSH_CSPSB0001");
168: throw new RDMDeadlockException(dbd);
169: }
170: catch (DbException dbe) {
171: throw new RDMException(dbe);
172: }
173: }*/
174:
175: }
|