1PMEMKV_TX(3) PMEMKV Programmer's Manual PMEMKV_TX(3)
2
3
4
6 pmemkv_tx - Transactions API for libpmemkv
7
8 This API is EXPERIMENTAL and might change.
9
11 #include <libpmemkv.h>
12
13 int pmemkv_tx_begin(pmemkv_db *db, pmemkv_tx **tx);
14 int pmemkv_tx_put(pmemkv_tx *tx, const char *k, size_t kb, const char *v, size_t vb);
15 int pmemkv_tx_remove(pmemkv_tx *tx, const char *k, size_t kb);
16 int pmemkv_tx_commit(pmemkv_tx *tx);
17 void pmemkv_tx_abort(pmemkv_tx *tx);
18 void pmemkv_tx_end(pmemkv_tx *tx);
19
21 The transaction allows grouping put and remove operations into a single
22 atomic action (with respect to persistence and concurrency). Concur‐
23 rent engines provide transactions with ACID (atomicity, consistency,
24 isolation, durability) properties. Transactions for single threaded
25 engines provide atomicity, consistency and durability. Actions in a
26 transaction are executed in the order in which they were called.
27
28 int pmemkv_tx_begin(pmemkv_db *db, pmemkv_tx **tx);
29 Starts a pmemkv transaction and stores a pointer to a pmemkv_tx
30 instance in *tx.
31
32 int pmemkv_tx_put(pmemkv_tx *tx, const char *k, size_t kb, const char
33 *v, size_t vb);
34 Inserts a key-value pair into pmemkv database. kb is the length
35 of the key k and vb is the length of value v. When this func‐
36 tion returns, caller is free to reuse both buffers. The insert‐
37 ed element is visible only after calling pmemkv_tx_commit.
38
39 int pmemkv_tx_remove(pmemkv_tx *tx, const char *k, size_t kb);
40 Removes record with the key k of length kb. The removed ele‐
41 ments are still visible until calling pmemkv_tx_commit. This
42 function will succeed even if there is no element in the data‐
43 base.
44
45 int pmemkv_tx_commit(pmemkv_tx *tx);
46 Commits the transaction. All operations of this transaction are
47 applied as a single power fail-safe atomic action.
48
49 void pmemkv_tx_abort(pmemkv_tx *tx);
50 Discards all uncommitted operations.
51
52 void pmemkv_tx_end(pmemkv_tx *tx);
53 Deletes the pmemkv transaction object and discards all uncommit‐
54 ted operations.
55
56 ERRORS
57 Each function, except for pmemkv_tx_abort() and pmemkv_tx_end() returns
58 status. Possible return values are listed in libpmemkv(3).
59
61 The following example is taken from examples/pmemkv_transaction_c di‐
62 rectory.
63
64 Usage of pmemkv transaction in C:
65
66 #include <assert.h>
67 #include <libpmemkv.h>
68 #include <stdio.h>
69 #include <stdlib.h>
70 #include <string.h>
71
72 #define ASSERT(expr) \
73 do { \
74 if (!(expr)) \
75 puts(pmemkv_errormsg()); \
76 assert(expr); \
77 } while (0)
78
79 #define LOG(msg) puts(msg)
80
81 /*
82 * This example expects a path to already created database pool.
83 *
84 * To create a pool use one of the following commands.
85 *
86 * For regular pools use:
87 * pmempool create -l -s 1G "pmemkv_radix" obj path_to_a_pool
88 *
89 * For poolsets use:
90 * pmempool create -l "pmemkv_radix" obj ../examples/example.poolset
91 */
92 int main(int argc, char *argv[])
93 {
94 if (argc < 2) {
95 printf("Usage: %s pool\n", argv[0]);
96 exit(1);
97 }
98
99 /* See libpmemkv_config(3) for more detailed example of config creation */
100 LOG("Creating config");
101 pmemkv_config *cfg = pmemkv_config_new();
102 ASSERT(cfg != NULL);
103
104 int s = pmemkv_config_put_path(cfg, argv[1]);
105 ASSERT(s == PMEMKV_STATUS_OK);
106
107 LOG("Opening pmemkv database with 'radix' engine");
108 pmemkv_db *db = NULL;
109 s = pmemkv_open("radix", cfg, &db);
110 ASSERT(s == PMEMKV_STATUS_OK);
111 ASSERT(db != NULL);
112
113 const char *key1 = "key1";
114 const char *value1 = "value1";
115 const char *key2 = "key2";
116 const char *value2 = "value2";
117 const char *key3 = "key3";
118 const char *value3 = "value3";
119
120 LOG("Putting new key");
121 s = pmemkv_put(db, key1, strlen(key1), value1, strlen(value1));
122 ASSERT(s == PMEMKV_STATUS_OK);
123
124 LOG("Starting a tx");
125 pmemkv_tx *tx;
126 s = pmemkv_tx_begin(db, &tx);
127 ASSERT(s == PMEMKV_STATUS_OK);
128
129 s = pmemkv_tx_remove(tx, key1, strlen(key1));
130 s = pmemkv_tx_put(tx, key2, strlen(key2), value2, strlen(value2));
131 s = pmemkv_tx_put(tx, key3, strlen(key3), value3, strlen(value3));
132
133 /* Until transaction is committed, changes are not visible */
134 s = pmemkv_exists(db, key1, strlen(key1));
135 ASSERT(s == PMEMKV_STATUS_OK);
136 s = pmemkv_exists(db, key2, strlen(key2));
137 ASSERT(s == PMEMKV_STATUS_NOT_FOUND);
138 s = pmemkv_exists(db, key3, strlen(key3));
139 ASSERT(s == PMEMKV_STATUS_NOT_FOUND);
140
141 s = pmemkv_tx_commit(tx);
142 ASSERT(s == PMEMKV_STATUS_OK);
143
144 /* Changes are now visible and pmemkv_tx object is destroyed */
145 s = pmemkv_exists(db, key1, strlen(key1));
146 ASSERT(s == PMEMKV_STATUS_NOT_FOUND);
147 s = pmemkv_exists(db, key2, strlen(key2));
148 ASSERT(s == PMEMKV_STATUS_OK);
149 s = pmemkv_exists(db, key3, strlen(key3));
150 ASSERT(s == PMEMKV_STATUS_OK);
151
152 LOG("Ending transaction");
153 pmemkv_tx_end(tx);
154
155 LOG("Closing database");
156 pmemkv_close(db);
157
158 return 0;
159 }
160
162 libpmemkv(7), libpmemkv(3) and <https://pmem.io>
163
164
165
166PMEMKV - pmemkv version 1.5.0 2022-01-28 PMEMKV_TX(3)