1PMEMKV_TX(3)              PMEMKV Programmer's Manual              PMEMKV_TX(3)
2
3
4

NAME

6       pmemkv_tx - Transactions API for libpmemkv
7
8       This API is EXPERIMENTAL and might change.
9

SYNOPSIS

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

DESCRIPTION

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

EXAMPLE

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

SEE ALSO

162       libpmemkv(7), libpmemkv(3) and <https://pmem.io>
163
164
165
166PMEMKV - pmemkv version 1.5.0     2022-01-28                      PMEMKV_TX(3)
Impressum