~ubuntu-branches/ubuntu/maverick/evolution-data-server/maverick-proposed

« back to all changes in this revision

Viewing changes to libdb/docs/ref/transapp/inc.html

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-05-17 17:02:06 UTC
  • mfrom: (1.1.79 upstream) (1.6.12 experimental)
  • Revision ID: james.westby@ubuntu.com-20100517170206-4ufr52vwrhh26yh0
Tags: 2.30.1-1ubuntu1
* Merge from debian experimental. Remaining change:
  (LP: #42199, #229669, #173703, #360344, #508494)
  + debian/control:
    - add Vcs-Bzr tag
    - don't use libgnome
    - Use Breaks instead of Conflicts against evolution 2.25 and earlier.
  + debian/evolution-data-server.install,
    debian/patches/45_libcamel_providers_version.patch:
    - use the upstream versioning, not a Debian-specific one 
  + debian/libedata-book1.2-dev.install, debian/libebackend-1.2-dev.install,
    debian/libcamel1.2-dev.install, debian/libedataserverui1.2-dev.install:
    - install html documentation
  + debian/rules:
    - don't build documentation it's shipped with the tarball

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<!--$Id$-->
2
 
<!--Copyright 1997-2002 by Sleepycat Software, Inc.-->
3
 
<!--All rights reserved.-->
4
 
<!--See the file LICENSE for redistribution information.-->
5
 
<html>
6
 
<head>
7
 
<title>Berkeley DB Reference Guide: Isolation</title>
8
 
<meta name="description" content="Berkeley DB: An embedded database programmatic toolkit.">
9
 
<meta name="keywords" content="embedded,database,programmatic,toolkit,b+tree,btree,hash,hashing,transaction,transactions,locking,logging,access method,access methods,java,C,C++">
10
 
</head>
11
 
<body bgcolor=white>
12
 
<table width="100%"><tr valign=top>
13
 
<td><h3><dl><dt>Berkeley DB Reference Guide:<dd>Berkeley DB Transactional Data Store Applications</dl></h3></td>
14
 
<td align=right><a href="../../ref/transapp/atomicity.html"><img src="../../images/prev.gif" alt="Prev"></a><a href="../../reftoc.html"><img src="../../images/ref.gif" alt="Ref"></a><a href="../../ref/transapp/read.html"><img src="../../images/next.gif" alt="Next"></a>
15
 
</td></tr></table>
16
 
<p>
17
 
<h1 align=center>Isolation</h1>
18
 
<p>The third reason listed for using transactions was <i>isolation</i>.
19
 
Consider an application suite in which multiple threads of control
20
 
(multiple processes or threads in one or more processes) are changing
21
 
the values associated with a key in one or more databases.  Specifically,
22
 
they are taking the current value, incrementing it, and then storing it
23
 
back into the database.
24
 
<p>Such an application requires isolation.  Because we want to change a value
25
 
in the database, we must make sure that after we read it, no other thread
26
 
of control modifies it.  For example, assume that both thread #1 and
27
 
thread #2 are doing similar operations in the database, where thread #1
28
 
is incrementing records by 3, and thread #2 is incrementing records by
29
 
5.  We want to increment the record by a total of 8.  If the operations
30
 
interleave in the right (well, wrong) order, that is not what will
31
 
happen:
32
 
<p><blockquote><pre>thread #1  <b>read</b> record: the value is 2
33
 
thread #2  <b>read</b> record: the value is 2
34
 
thread #2  <b>write</b> record + 5 back into the database (new value 7)
35
 
thread #1  <b>write</b> record + 3 back into the database (new value 5)</pre></blockquote>
36
 
<p>As you can see, instead of incrementing the record by a total of 8,
37
 
we've incremented it only by 3 because thread #1 overwrote thread #2's
38
 
change.  By wrapping the operations in transactions, we ensure that this
39
 
cannot happen.  In a transaction, when the first thread reads the
40
 
record, locks are acquired that will not be released until the
41
 
transaction finishes, guaranteeing that all other readers and writers
42
 
will block, waiting for the first thread's transaction to complete (or
43
 
to be aborted).
44
 
<p>Here is an example function that does transaction-protected increments
45
 
on database records to ensure isolation:
46
 
<p><blockquote><pre>int
47
 
main(int argc, char *argv)
48
 
{
49
 
        extern char *optarg;
50
 
        extern int optind;
51
 
        DB *db_cats, *db_color, *db_fruit;
52
 
        DB_ENV *dbenv;
53
 
        pthread_t ptid;
54
 
        int ch;
55
 
<p>
56
 
        while ((ch = getopt(argc, argv, "")) != EOF)
57
 
                switch (ch) {
58
 
                case '?':
59
 
                default:
60
 
                        usage();
61
 
                }
62
 
        argc -= optind;
63
 
        argv += optind;
64
 
<p>
65
 
        env_dir_create();
66
 
        env_open(&dbenv);
67
 
<p>
68
 
        /* Open database: Key is fruit class; Data is specific type. */
69
 
        db_open(dbenv, &db_fruit, "fruit", 0);
70
 
<p>
71
 
        /* Open database: Key is a color; Data is an integer. */
72
 
        db_open(dbenv, &db_color, "color", 0);
73
 
<p>
74
 
        /*
75
 
         * Open database:
76
 
         *      Key is a name; Data is: company name, cat breeds.
77
 
         */
78
 
        db_open(dbenv, &db_cats, "cats", 1);
79
 
<p>
80
 
        add_fruit(dbenv, db_fruit, "apple", "yellow delicious");
81
 
<p>
82
 
<b>     add_color(dbenv, db_color, "blue", 0);
83
 
        add_color(dbenv, db_color, "blue", 3);</b>
84
 
<p>
85
 
        return (0);
86
 
}
87
 
<p>
88
 
<b>int
89
 
add_color(DB_ENV *dbenv, DB *dbp, char *color, int increment)
90
 
{
91
 
        DBT key, data;
92
 
        DB_TXN *tid;
93
 
        int fail, original, ret, t_ret;
94
 
        char buf64;
95
 
<p>
96
 
        /* Initialization. */
97
 
        memset(&key, 0, sizeof(key));
98
 
        key.data = color;
99
 
        key.size = strlen(color);
100
 
        memset(&data, 0, sizeof(data));
101
 
        data.flags = DB_DBT_MALLOC;
102
 
<p>
103
 
        for (fail = 0;;) {
104
 
                /* Begin the transaction. */
105
 
                if ((ret = dbenv-&gt;txn_begin(dbenv, NULL, &tid, 0)) != 0) {
106
 
                        dbenv-&gt;err(dbenv, ret, "DB_ENV-&gt;txn_begin");
107
 
                        exit (1);
108
 
                }
109
 
<p>
110
 
                /*
111
 
                 * Get the key.  If it exists, we increment the value.  If it
112
 
                 * doesn't exist, we create it.
113
 
                 */
114
 
                switch (ret = dbp-&gt;get(dbp, tid, &key, &data, 0)) {
115
 
                case 0:
116
 
                        original = atoi(data.data);
117
 
                        break;
118
 
                case DB_LOCK_DEADLOCK:
119
 
                default:
120
 
                        /* Retry the operation. */
121
 
                        if ((t_ret = tid-&gt;abort(tid)) != 0) {
122
 
                                dbenv-&gt;err(dbenv, t_ret, "DB_TXN-&gt;abort");
123
 
                                exit (1);
124
 
                        }
125
 
                        if (++fail == MAXIMUM_RETRY)
126
 
                                return (ret);
127
 
                        continue;
128
 
                case DB_NOTFOUND:
129
 
                        original = 0;
130
 
                        break;
131
 
                }
132
 
                if (data.data != NULL)
133
 
                        free(data.data);
134
 
<p>
135
 
                /* Create the new data item. */
136
 
                (void)snprintf(buf, sizeof(buf), "%d", original + increment);
137
 
                data.data = buf;
138
 
                data.size = strlen(buf) + 1;
139
 
<p>
140
 
                /* Store the new value. */
141
 
                switch (ret = dbp-&gt;put(dbp, tid, &key, &data, 0)) {
142
 
                case 0:
143
 
                        /* Success: commit the change. */
144
 
                        if ((ret = tid-&gt;commit(tid, 0)) != 0) {
145
 
                                dbenv-&gt;err(dbenv, ret, "DB_TXN-&gt;commit");
146
 
                                exit (1);
147
 
                        }
148
 
                        return (0);
149
 
                case DB_LOCK_DEADLOCK:
150
 
                default:
151
 
                        /* Retry the operation. */
152
 
                        if ((t_ret = tid-&gt;abort(tid)) != 0) {
153
 
                                dbenv-&gt;err(dbenv, t_ret, "DB_TXN-&gt;abort");
154
 
                                exit (1);
155
 
                        }
156
 
                        if (++fail == MAXIMUM_RETRY)
157
 
                                return (ret);
158
 
                        break;
159
 
                }
160
 
        }
161
 
}</b></pre></blockquote>
162
 
<table width="100%"><tr><td><br></td><td align=right><a href="../../ref/transapp/atomicity.html"><img src="../../images/prev.gif" alt="Prev"></a><a href="../../reftoc.html"><img src="../../images/ref.gif" alt="Ref"></a><a href="../../ref/transapp/read.html"><img src="../../images/next.gif" alt="Next"></a>
163
 
</td></tr></table>
164
 
<p><font size=1><a href="http://www.sleepycat.com">Copyright Sleepycat Software</a></font>
165
 
</body>
166
 
</html>