• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/db-4.8.30/examples_java/src/db/txn/
1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2005-2009 Oracle.  All rights reserved.
5 *
6 * $Id$
7 */
8
9package db.txn;
10
11import com.sleepycat.bind.EntryBinding;
12import com.sleepycat.bind.serial.StoredClassCatalog;
13import com.sleepycat.bind.serial.SerialBinding;
14import com.sleepycat.bind.tuple.StringBinding;
15
16import com.sleepycat.db.Cursor;
17import com.sleepycat.db.CursorConfig;
18import com.sleepycat.db.Database;
19import com.sleepycat.db.DatabaseEntry;
20import com.sleepycat.db.DatabaseException;
21import com.sleepycat.db.DeadlockException;
22import com.sleepycat.db.Environment;
23import com.sleepycat.db.LockMode;
24import com.sleepycat.db.OperationStatus;
25import com.sleepycat.db.Transaction;
26
27import java.io.UnsupportedEncodingException;
28import java.util.Random;
29
30public class DBWriter extends Thread
31{
32    private Database myDb = null;
33    private Environment myEnv = null;
34    private EntryBinding dataBinding = null;
35    private Random generator = new Random();
36    private boolean passTxn = false;
37
38
39    private static final int MAX_RETRY = 20;
40
41    private static String[] keys = {"key 1", "key 2", "key 3",
42                                    "key 4", "key 5", "key 6",
43                                    "key 7", "key 8", "key 9",
44                                    "key 10"};
45
46
47    // Constructor. Get our DB handles from here
48    // This consturctor allows us to indicate whether the
49    // txn handle should be handed to countRecords()
50    DBWriter(Environment env, Database db, StoredClassCatalog scc,
51        boolean passtxn)
52
53        throws DatabaseException {
54        myDb = db;
55        myEnv = env;
56        dataBinding = new SerialBinding(scc, PayloadData.class);
57
58        passTxn = passtxn;
59    }
60
61    // Constructor. Get our DB handles from here
62    DBWriter(Environment env, Database db, StoredClassCatalog scc)
63
64        throws DatabaseException {
65        myDb = db;
66        myEnv = env;
67        dataBinding = new SerialBinding(scc, PayloadData.class);
68    }
69
70    // Thread method that writes a series of records
71    // to the database using transaction protection.
72    // Deadlock handling is demonstrated here.
73    public void run () {
74        Transaction txn = null;
75
76        // Perform 50 transactions
77        for (int i=0; i<50; i++) {
78
79           boolean retry = true;
80           int retry_count = 0;
81           // while loop is used for deadlock retries
82           while (retry) {
83                // try block used for deadlock detection and
84                // general db exception handling
85                try {
86
87                    // Get a transaction
88                    txn = myEnv.beginTransaction(null, null);
89
90                    // Write 10 records to the db
91                    // for each transaction
92                    for (int j = 0; j < 10; j++) {
93                        // Get the key
94                        DatabaseEntry key = new DatabaseEntry();
95                        StringBinding.stringToEntry(keys[j], key);
96
97                        // Get the data
98                        PayloadData pd = new PayloadData(i+j, getName(),
99                            generator.nextDouble());
100                        DatabaseEntry data = new DatabaseEntry();
101                        dataBinding.objectToEntry(pd, data);
102
103                        // Do the put
104                        myDb.put(txn, key, data);
105                    }
106
107                    // commit
108                    System.out.println(getName() + " : committing txn : " + i);
109
110                    // This code block allows us to decide if txn handle is
111                    // passed to countRecords()
112                    //
113                    // TxnGuideInMemory requires a txn handle be handed to
114                    // countRecords(). The code self deadlocks if you don't.
115                    // TxnGuide has no such requirement because it supports
116                    // uncommitted reads.
117                    Transaction txnHandle = null;
118                    if (passTxn) { txnHandle = txn; }
119
120                    System.out.println(getName() + " : Found " +
121                        countRecords(txnHandle) + " records in the database.");
122                    try {
123                        txn.commit();
124                        txn = null;
125                    } catch (DatabaseException e) {
126                        System.err.println("Error on txn commit: " +
127                            e.toString());
128                    }
129                    retry = false;
130
131                } catch (DeadlockException de) {
132                    System.out.println("################# " + getName() +
133                        " : caught deadlock");
134                    // retry if necessary
135                    if (retry_count < MAX_RETRY) {
136                        System.err.println(getName() +
137                            " : Retrying operation.");
138                        retry = true;
139                        retry_count++;
140                    } else {
141                        System.err.println(getName() +
142                            " : out of retries. Giving up.");
143                        retry = false;
144                    }
145                } catch (DatabaseException e) {
146                    // abort and don't retry
147                    retry = false;
148                    System.err.println(getName() +
149                        " : caught exception: " + e.toString());
150                    System.err.println(getName() +
151                        " : errno: " + e.getErrno());
152                    e.printStackTrace();
153                } finally {
154                    if (txn != null) {
155                        try {
156                            txn.abort();
157                        } catch (Exception e) {
158                            System.err.println("Error aborting transaction: " +
159                                e.toString());
160                            e.printStackTrace();
161                        }
162                    }
163                }
164            }
165        }
166    }
167
168    // This simply counts the number of records contained in the
169    // database and returns the result. You can use this method
170    // in three ways:
171    //
172    // First call it with an active txn handle.
173    //
174    // Secondly, configure the cursor for dirty reads
175    //
176    // Third, call countRecords AFTER the writer has committed
177    //    its transaction.
178    //
179    // If you do none of these things, the writer thread will
180    // self-deadlock.
181    //
182    // Note that this method exists only for illustrative purposes.
183    // A more straight-forward way to count the number of records in
184    // a database is to use the Database.getStats() method.
185    private int countRecords(Transaction txn)  throws DatabaseException {
186        DatabaseEntry key = new DatabaseEntry();
187        DatabaseEntry data = new DatabaseEntry();
188        int count = 0;
189        Cursor cursor = null;
190
191        try {
192            // Get the cursor
193            CursorConfig cc = new CursorConfig();
194            // setReadUncommitted is ignored if the database was not
195            // opened for uncommitted read support. TxnGuide opens
196            // its database in this way, TxnGuideInMemory does not.
197            cc.setReadUncommitted(true);
198            cursor = myDb.openCursor(txn, cc);
199            while (cursor.getNext(key, data, LockMode.DEFAULT) ==
200                    OperationStatus.SUCCESS) {
201
202                    count++;
203            }
204        } finally {
205            if (cursor != null) {
206                cursor.close();
207            }
208        }
209
210        return count;
211
212    }
213}
214