01 #include
02 #include
03 #include
04
05 #define ENVDIR "test" // ensure that this is already created
06 #define DBNAME "test.db"
07
08 #define MAXRETRY 10 // number of times we'll attempt txn
09
10 int main(int argc, char **argv)
11 {
12 DB *dbp;
13 DBT key,data;
14 DBC *dbcp;
15 DB_ENV *dbenv;
16 DB_TXN *tid;
17 int ret;
18 int i = 0;
19
20 if((ret = db_env_create(&dbenv,0)) != 0) {
21 fprintf(stderr,"db_env_create(): %s\n",
22 db_strerror(ret));
23 exit(1);
24 }
25
26 /* Open transactional environment: create if it doesn't exist,
27 * run recovery, init underlying subsystems, open 0644 */
28
29 if((ret = dbenv->open(dbenv,ENVDIR,DB_CREATE | DB_INIT_LOCK |
30 DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_RECOVER, 0644)) != 0) {
31
32 dbenv->err(dbenv,ret,"dbenv->open");
33 dbenv->close(dbenv,0);
34 exit(1);
35 }
36
37 if((ret = db_create(&dbp,dbenv,0)) != 0) {
38 dbenv->err(dbenv,ret,"db_create");
39 dbenv->close(dbenv,0);
40 exit(1);
41 }
42
43 if((ret = dbp->set_flags(dbp,DB_DUP)) != 0) {
44 dbenv->err(dbenv,ret,"dbp->set_flags");
45 dbenv->close(dbenv,0);
46 exit(1);
47 }
48
49 if((ret = dbp->open(dbp,DBNAME,NULL, DB_BTREE, DB_CREATE, 0644)) != 0) {
50 dbenv->err(dbenv,ret,"dbp->open()");
51 dbenv->close(dbenv,0);
52 exit(1);
53 }
54
55 memset(&key,0,sizeof(key));
56 memset(&data,0,sizeof(data));
57
58 key.data = strdup(argv[1]);
59 key.size = strlen(argv[1]);
60
61 data.data = strdup(argv[2]);
62 data.size = strlen(argv[2]);
63
64 while(i<MAXRETRY) {
65 i++;
66 if ((ret = dbenv->txn_begin(dbenv, NULL, &tid, 0)) != 0) {
67 dbenv->err(dbenv, ret, "dbenv->txn_begin");
68 dbenv->close(dbenv,0);
69 exit (1);
70 }
71 /* encapsulate the cursor operation in the transaction */
72
73 if((ret = dbp->cursor(dbp,tid,&dbcp,0)) != 0) {
74 dbenv->err(dbenv, ret, "dbp->cursor()");
75 dbenv->close(dbenv,0);
76 exit(1);
77 }
78
79 if((ret = dbcp->c_put(dbcp,&key,&data,DB_KEYFIRST)) != 0) {
80 /* we might have a deadlock
81 * retry: close the cursor and abort */
82 if((ret = dbcp->c_close(dbcp)) != 0) {
83 dbenv->err(dbenv,ret,"dbcp->c_close");
84 dbenv->close(dbenv,0);
85 exit(1);
86 }
87 if((ret = tid->abort(tid)) != 0) {
88 dbenv->err(dbenv,ret,"tid->abort()");
89 dbenv->close(dbenv,0);
90 exit(1);
91 }
92 continue;
93 } else {
94 /* successful */
95 if((ret = dbcp->c_close(dbcp)) != 0) {
96 dbenv->err(dbenv,ret,"dbcp->c_close at txn commit");
97 dbenv->close(dbenv,0);
98 exit(1);
99 }
100 if((ret = tid->commit(tid,0)) != 0) {
101 dbenv->err(dbenv,ret,"tid->commit()");
102 dbenv->close(dbenv,0);
103 exit(1);
104 }
105 break;
106 }
107 }
108 dbenv->close(dbenv,0);
109 exit(0);
110 }