summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2012-09-19 18:17:22 +1000
committerMichael Cahill <michael.cahill@wiredtiger.com>2012-09-19 18:17:22 +1000
commit3ca6943b109863e58bb37f6873963b65ddedf895 (patch)
treefe0f457c82969e8a19fb58666e4e56ce2045b3e0
parent6234acd24828049279d4bff3f22223d4afb4bdfd (diff)
downloadmongo-3ca6943b109863e58bb37f6873963b65ddedf895.tar.gz
Implement auto-commit of transactions at the API.
This simplifies code that tried to get the effect of auto-commit internally. closes #309, refs #310
-rw-r--r--dist/s_style2
-rw-r--r--src/cursor/cur_backup.c6
-rw-r--r--src/cursor/cur_bulk.c9
-rw-r--r--src/cursor/cur_dump.c10
-rw-r--r--src/cursor/cur_file.c30
-rw-r--r--src/cursor/cur_index.c16
-rw-r--r--src/cursor/cur_stat.c16
-rw-r--r--src/cursor/cur_std.c10
-rw-r--r--src/cursor/cur_table.c32
-rw-r--r--src/include/api.h36
-rw-r--r--src/include/txn.i71
-rw-r--r--src/lsm/lsm_cursor.c39
-rw-r--r--src/txn/txn.c2
13 files changed, 130 insertions, 149 deletions
diff --git a/dist/s_style b/dist/s_style
index 099da9808b2..b8f55cc5b89 100644
--- a/dist/s_style
+++ b/dist/s_style
@@ -55,7 +55,7 @@ for f in `find examples ext src test -name '*.[chisy]' -o -name '*.in' |
fi
# Early exits from critical loops
- sed -n -e '/API_CALL/,/API_END/{=;p;}' \
+ sed -n -e '/API_CALL.*;$/,/API_END.*;/{=;p;}' \
-e '/va_start/,/va_end/{=;p;}' $f | \
sed 'N;s/\n/:/' | \
egrep 'return|WT_RET' | \
diff --git a/src/cursor/cur_backup.c b/src/cursor/cur_backup.c
index d89ca1166ef..6373533c720 100644
--- a/src/cursor/cur_backup.c
+++ b/src/cursor/cur_backup.c
@@ -34,7 +34,7 @@ __curbackup_next(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cb = (WT_CURSOR_BACKUP *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, next, NULL);
+ CURSOR_API_CALL(cursor, session, next, NULL);
if (cb->list == NULL || cb->list[cb->next] == NULL) {
F_CLR(cursor, WT_CURSTD_KEY_SET);
@@ -62,7 +62,7 @@ __curbackup_reset(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cb = (WT_CURSOR_BACKUP *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, reset, NULL);
+ CURSOR_API_CALL(cursor, session, reset, NULL);
cb->next = 0;
F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
@@ -85,7 +85,7 @@ __curbackup_close(WT_CURSOR *cursor)
int tret;
cb = (WT_CURSOR_BACKUP *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, close, NULL);
+ CURSOR_API_CALL(cursor, session, close, NULL);
/* Free the list of files. */
if (cb->list != NULL) {
diff --git a/src/cursor/cur_bulk.c b/src/cursor/cur_bulk.c
index 52412166051..ea503edea46 100644
--- a/src/cursor/cur_bulk.c
+++ b/src/cursor/cur_bulk.c
@@ -21,7 +21,12 @@ __curbulk_insert(WT_CURSOR *cursor)
cbulk = (WT_CURSOR_BULK *)cursor;
btree = cbulk->cbt.btree;
- CURSOR_API_CALL_NOCONF(cursor, session, insert, btree);
+ /*
+ * Bulk cursor inserts are updates, but don't need auto-commit
+ * transactions because they are single-threaded and not visible until
+ * the bulk cursor is closed.
+ */
+ CURSOR_API_CALL(cursor, session, insert, btree);
if (btree->type == BTREE_ROW)
WT_CURSOR_NEEDKEY(cursor);
WT_CURSOR_NEEDVALUE(cursor);
@@ -46,7 +51,7 @@ __curbulk_close(WT_CURSOR *cursor)
cbulk = (WT_CURSOR_BULK *)cursor;
btree = cbulk->cbt.btree;
- CURSOR_API_CALL_NOCONF(cursor, session, close, btree);
+ CURSOR_API_CALL(cursor, session, close, btree);
WT_TRET(__wt_bulk_end(cbulk));
if (btree != NULL) {
WT_ASSERT(session, session->btree == btree);
diff --git a/src/cursor/cur_dump.c b/src/cursor/cur_dump.c
index 71096bd2aea..084175fa51f 100644
--- a/src/cursor/cur_dump.c
+++ b/src/cursor/cur_dump.c
@@ -59,7 +59,7 @@ __curdump_get_key(WT_CURSOR *cursor, ...)
cdump = (WT_CURSOR_DUMP *)cursor;
child = cdump->child;
- CURSOR_API_CALL_NOCONF(cursor, session, get_key, NULL);
+ CURSOR_API_CALL(cursor, session, get_key, NULL);
if (WT_CURSOR_RECNO(cursor) && !F_ISSET(cursor, WT_CURSTD_RAW)) {
WT_ERR(child->get_key(child, &recno));
@@ -131,7 +131,7 @@ __curdump_set_key(WT_CURSOR *cursor, ...)
cdump = (WT_CURSOR_DUMP *)cursor;
child = cdump->child;
- CURSOR_API_CALL_NOCONF(cursor, session, set_key, NULL);
+ CURSOR_API_CALL(cursor, session, set_key, NULL);
va_start(ap, cursor);
if (F_ISSET(cursor, WT_CURSTD_RAW))
@@ -175,7 +175,7 @@ __curdump_get_value(WT_CURSOR *cursor, ...)
cdump = (WT_CURSOR_DUMP *)cursor;
child = cdump->child;
- CURSOR_API_CALL_NOCONF(cursor, session, get_value, NULL);
+ CURSOR_API_CALL(cursor, session, get_value, NULL);
WT_ERR(child->get_value(child, &item));
@@ -211,7 +211,7 @@ __curdump_set_value(WT_CURSOR *cursor, ...)
cdump = (WT_CURSOR_DUMP *)cursor;
child = cdump->child;
- CURSOR_API_CALL_NOCONF(cursor, session, set_value, NULL);
+ CURSOR_API_CALL(cursor, session, set_value, NULL);
va_start(ap, cursor);
if (F_ISSET(cursor, WT_CURSTD_RAW))
@@ -273,7 +273,7 @@ __curdump_close(WT_CURSOR *cursor)
cdump = (WT_CURSOR_DUMP *)cursor;
child = cdump->child;
- CURSOR_API_CALL_NOCONF(cursor, session, get_key, NULL);
+ CURSOR_API_CALL(cursor, session, get_key, NULL);
if (child != NULL)
WT_TRET(child->close(child));
/* We shared the child's URI. */
diff --git a/src/cursor/cur_file.c b/src/cursor/cur_file.c
index 98c3fc04989..ff49a61777c 100644
--- a/src/cursor/cur_file.c
+++ b/src/cursor/cur_file.c
@@ -19,7 +19,7 @@ __curfile_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp)
WT_SESSION_IMPL *session;
cbt = (WT_CURSOR_BTREE *)a;
- CURSOR_API_CALL_NOCONF(a, session, compare, cbt->btree);
+ CURSOR_API_CALL(a, session, compare, cbt->btree);
/*
* Confirm both cursors refer to the same source and have keys, then
@@ -51,7 +51,7 @@ __curfile_next(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, next, cbt->btree);
+ CURSOR_API_CALL(cursor, session, next, cbt->btree);
ret = __wt_btcur_next((WT_CURSOR_BTREE *)cursor, 0);
API_END(session);
@@ -71,7 +71,7 @@ __curfile_next_random(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, next, cbt->btree);
+ CURSOR_API_CALL(cursor, session, next, cbt->btree);
ret = __wt_btcur_next_random(cbt);
API_END(session);
@@ -90,7 +90,7 @@ __curfile_prev(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, prev, cbt->btree);
+ CURSOR_API_CALL(cursor, session, prev, cbt->btree);
ret = __wt_btcur_prev((WT_CURSOR_BTREE *)cursor, 0);
API_END(session);
@@ -109,7 +109,7 @@ __curfile_reset(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, reset, cbt->btree);
+ CURSOR_API_CALL(cursor, session, reset, cbt->btree);
ret = __wt_btcur_reset(cbt);
API_END(session);
@@ -128,7 +128,7 @@ __curfile_search(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, search, cbt->btree);
+ CURSOR_API_CALL(cursor, session, search, cbt->btree);
WT_CURSOR_NEEDKEY(cursor);
ret = __wt_btcur_search(cbt);
err: API_END(session);
@@ -148,7 +148,7 @@ __curfile_search_near(WT_CURSOR *cursor, int *exact)
WT_SESSION_IMPL *session;
cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, search_near, cbt->btree);
+ CURSOR_API_CALL(cursor, session, search_near, cbt->btree);
WT_CURSOR_NEEDKEY(cursor);
ret = __wt_btcur_search_near(cbt, exact);
err: API_END(session);
@@ -168,12 +168,12 @@ __curfile_insert(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, insert, cbt->btree);
+ CURSOR_UPDATE_API_CALL(cursor, session, insert, cbt->btree);
if (!F_ISSET(cursor, WT_CURSTD_APPEND))
WT_CURSOR_NEEDKEY(cursor);
WT_CURSOR_NEEDVALUE(cursor);
ret = __wt_btcur_insert((WT_CURSOR_BTREE *)cursor);
-err: API_END_TXN_ERROR(session, ret);
+err: CURSOR_UPDATE_API_END(session, ret);
return (ret);
}
@@ -190,11 +190,11 @@ __curfile_update(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, update, cbt->btree);
+ CURSOR_UPDATE_API_CALL(cursor, session, update, cbt->btree);
WT_CURSOR_NEEDKEY(cursor);
WT_CURSOR_NEEDVALUE(cursor);
ret = __wt_btcur_update((WT_CURSOR_BTREE *)cursor);
-err: API_END_TXN_ERROR(session, ret);
+err: CURSOR_UPDATE_API_END(session, ret);
return (ret);
}
@@ -211,10 +211,10 @@ __curfile_remove(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, remove, cbt->btree);
+ CURSOR_UPDATE_API_CALL(cursor, session, remove, cbt->btree);
WT_CURSOR_NEEDKEY(cursor);
ret = __wt_btcur_remove((WT_CURSOR_BTREE *)cursor);
-err: API_END_TXN_ERROR(session, ret);
+err: CURSOR_UPDATE_API_END(session, ret);
return (ret);
}
@@ -259,14 +259,14 @@ __curfile_close(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cbt = (WT_CURSOR_BTREE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, close, cbt->btree);
+ CURSOR_API_CALL(cursor, session, close, cbt->btree);
WT_TRET(__wt_btcur_close(cbt));
if (session->btree != NULL)
WT_TRET(__wt_session_release_btree(session));
/* The URI is owned by the btree handle. */
cursor->uri = NULL;
WT_TRET(__wt_cursor_close(cursor));
- API_END_TXN_ERROR(session, ret);
+ API_END(session);
return (ret);
}
diff --git a/src/cursor/cur_index.c b/src/cursor/cur_index.c
index 56824e6cfb3..39966177fda 100644
--- a/src/cursor/cur_index.c
+++ b/src/cursor/cur_index.c
@@ -21,7 +21,7 @@ __curindex_get_value(WT_CURSOR *cursor, ...)
va_list ap;
cindex = (WT_CURSOR_INDEX *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, get_value, NULL);
+ CURSOR_API_CALL(cursor, session, get_value, NULL);
WT_CURSOR_NEEDVALUE(cursor);
va_start(ap, cursor);
@@ -53,7 +53,7 @@ __curindex_set_value(WT_CURSOR *cursor, ...)
WT_DECL_RET;
WT_SESSION_IMPL *session;
- CURSOR_API_CALL_NOCONF(cursor, session, set_value, NULL);
+ CURSOR_API_CALL(cursor, session, set_value, NULL);
WT_UNUSED(ret);
cursor->saved_err = ENOTSUP;
F_CLR(cursor, WT_CURSTD_VALUE_SET);
@@ -115,7 +115,7 @@ __curindex_next(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cindex = (WT_CURSOR_INDEX *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, next, cindex->cbt.btree);
+ CURSOR_API_CALL(cursor, session, next, cindex->cbt.btree);
if ((ret = __wt_btcur_next(&cindex->cbt, 0)) == 0)
ret = __curindex_move(cindex);
API_END(session);
@@ -135,7 +135,7 @@ __curindex_prev(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cindex = (WT_CURSOR_INDEX *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, prev, cindex->cbt.btree);
+ CURSOR_API_CALL(cursor, session, prev, cindex->cbt.btree);
if ((ret = __wt_btcur_prev(&cindex->cbt, 0)) == 0)
ret = __curindex_move(cindex);
API_END(session);
@@ -157,7 +157,7 @@ __curindex_reset(WT_CURSOR *cursor)
int i;
cindex = (WT_CURSOR_INDEX *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, reset, cindex->cbt.btree);
+ CURSOR_API_CALL(cursor, session, reset, cindex->cbt.btree);
WT_TRET(__wt_btcur_reset(&cindex->cbt));
for (i = 0, cp = cindex->cg_cursors;
@@ -186,7 +186,7 @@ __curindex_search(WT_CURSOR *cursor)
int exact;
cindex = (WT_CURSOR_INDEX *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, search, cindex->cbt.btree);
+ CURSOR_API_CALL(cursor, session, search, cindex->cbt.btree);
/*
* XXX
@@ -250,7 +250,7 @@ __curindex_search_near(WT_CURSOR *cursor, int *exact)
WT_SESSION_IMPL *session;
cindex = (WT_CURSOR_INDEX *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, search_near, cindex->cbt.btree);
+ CURSOR_API_CALL(cursor, session, search_near, cindex->cbt.btree);
if ((ret = __wt_btcur_search_near(&cindex->cbt, exact)) == 0)
ret = __curindex_move(cindex);
API_END(session);
@@ -277,7 +277,7 @@ __curindex_close(WT_CURSOR *cursor)
idx = cindex->index;
btree = cindex->cbt.btree;
- CURSOR_API_CALL_NOCONF(cursor, session, close, btree);
+ CURSOR_API_CALL(cursor, session, close, btree);
for (i = 0, cp = (cindex)->cg_cursors;
i < WT_COLGROUPS(cindex->table); i++, cp++)
diff --git a/src/cursor/cur_stat.c b/src/cursor/cur_stat.c
index 0747aa1efe2..f24e8bbe515 100644
--- a/src/cursor/cur_stat.c
+++ b/src/cursor/cur_stat.c
@@ -44,7 +44,7 @@ __curstat_get_key(WT_CURSOR *cursor, ...)
va_list ap;
cst = (WT_CURSOR_STAT *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, get_key, cst->btree);
+ CURSOR_API_CALL(cursor, session, get_key, cst->btree);
va_start(ap, cursor);
WT_CURSOR_NEEDKEY(cursor);
@@ -82,7 +82,7 @@ __curstat_get_value(WT_CURSOR *cursor, ...)
size_t size;
cst = (WT_CURSOR_STAT *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, get_value, cst->btree);
+ CURSOR_API_CALL(cursor, session, get_value, cst->btree);
va_start(ap, cursor);
WT_CURSOR_NEEDVALUE(cursor);
@@ -123,7 +123,7 @@ __curstat_set_key(WT_CURSOR *cursor, ...)
va_list ap;
cst = (WT_CURSOR_STAT *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, set_key, cst->btree);
+ CURSOR_API_CALL(cursor, session, set_key, cst->btree);
va_start(ap, cursor);
if (F_ISSET(cursor, WT_CURSTD_RAW)) {
@@ -165,7 +165,7 @@ __curstat_next(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cst = (WT_CURSOR_STAT *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, next, cst->btree);
+ CURSOR_API_CALL(cursor, session, next, cst->btree);
/* Move to the next item. */
if (cst->notpositioned) {
@@ -197,7 +197,7 @@ __curstat_prev(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cst = (WT_CURSOR_STAT *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, prev, cst->btree);
+ CURSOR_API_CALL(cursor, session, prev, cst->btree);
/* Move to the previous item. */
if (cst->notpositioned) {
@@ -229,7 +229,7 @@ __curstat_reset(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cst = (WT_CURSOR_STAT *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, reset, cst->btree);
+ CURSOR_API_CALL(cursor, session, reset, cst->btree);
cst->notpositioned = 1;
F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
@@ -250,7 +250,7 @@ __curstat_search(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cst = (WT_CURSOR_STAT *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, search, cst->btree);
+ CURSOR_API_CALL(cursor, session, search, cst->btree);
WT_CURSOR_NEEDKEY(cursor);
F_CLR(cursor, WT_CURSTD_VALUE_SET);
@@ -278,7 +278,7 @@ __curstat_close(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
cst = (WT_CURSOR_STAT *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, close, cst->btree);
+ CURSOR_API_CALL(cursor, session, close, cst->btree);
if (cst->clear_func)
cst->clear_func(cst->stats_first);
diff --git a/src/cursor/cur_std.c b/src/cursor/cur_std.c
index 0ae26c0ef0b..82eceb945a6 100644
--- a/src/cursor/cur_std.c
+++ b/src/cursor/cur_std.c
@@ -154,7 +154,7 @@ __wt_cursor_get_keyv(WT_CURSOR *cursor, uint32_t flags, va_list ap)
size_t size;
const char *fmt;
- CURSOR_API_CALL_NOCONF(cursor, session, get_key, NULL);
+ CURSOR_API_CALL(cursor, session, get_key, NULL);
WT_CURSOR_NEEDKEY(cursor);
if (WT_CURSOR_RECNO(cursor)) {
@@ -195,7 +195,7 @@ __wt_cursor_set_keyv(WT_CURSOR *cursor, uint32_t flags, va_list ap)
va_list ap_copy;
const char *fmt, *str;
- CURSOR_API_CALL_NOCONF(cursor, session, set_key, NULL);
+ CURSOR_API_CALL(cursor, session, set_key, NULL);
/* Fast path some common cases: single strings or byte arrays. */
if (WT_CURSOR_RECNO(cursor)) {
@@ -265,7 +265,7 @@ __wt_cursor_get_value(WT_CURSOR *cursor, ...)
const char *fmt;
va_list ap;
- CURSOR_API_CALL_NOCONF(cursor, session, get_value, NULL);
+ CURSOR_API_CALL(cursor, session, get_value, NULL);
WT_CURSOR_NEEDVALUE(cursor);
va_start(ap, cursor);
@@ -294,7 +294,7 @@ __wt_cursor_set_value(WT_CURSOR *cursor, ...)
size_t sz;
va_list ap;
- CURSOR_API_CALL_NOCONF(cursor, session, set_value, NULL);
+ CURSOR_API_CALL(cursor, session, set_value, NULL);
va_start(ap, cursor);
fmt = F_ISSET(cursor,
@@ -354,7 +354,7 @@ __wt_cursor_close(WT_CURSOR *cursor)
WT_DECL_RET;
WT_SESSION_IMPL *session;
- CURSOR_API_CALL_NOCONF(cursor, session, close, NULL);
+ CURSOR_API_CALL(cursor, session, close, NULL);
__wt_buf_free(session, &cursor->key);
__wt_buf_free(session, &cursor->value);
diff --git a/src/cursor/cur_table.c b/src/cursor/cur_table.c
index 05b1b07dc16..c2884d22101 100644
--- a/src/cursor/cur_table.c
+++ b/src/cursor/cur_table.c
@@ -73,7 +73,7 @@ __wt_curtable_get_value(WT_CURSOR *cursor, ...)
ctable = (WT_CURSOR_TABLE *)cursor;
primary = *ctable->cg_cursors;
- CURSOR_API_CALL_NOCONF(cursor, session, get_value, NULL);
+ CURSOR_API_CALL(cursor, session, get_value, NULL);
WT_CURSOR_NEEDVALUE(primary);
va_start(ap, cursor);
@@ -144,7 +144,7 @@ __wt_curtable_set_value(WT_CURSOR *cursor, ...)
int i;
ctable = (WT_CURSOR_TABLE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, set_value, NULL);
+ CURSOR_API_CALL(cursor, session, set_value, NULL);
va_start(ap, cursor);
if (F_ISSET(cursor,
@@ -182,7 +182,7 @@ __curtable_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp)
WT_DECL_RET;
WT_SESSION_IMPL *session;
- CURSOR_API_CALL_NOCONF(a, session, compare, NULL);
+ CURSOR_API_CALL(a, session, compare, NULL);
/*
* Confirm both cursors refer to the same source and have keys, then
@@ -214,7 +214,7 @@ __curtable_next(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
ctable = (WT_CURSOR_TABLE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, next, NULL);
+ CURSOR_API_CALL(cursor, session, next, NULL);
APPLY_CG(ctable, next);
API_END(session);
@@ -236,7 +236,7 @@ __curtable_next_random(WT_CURSOR *cursor)
int i;
ctable = (WT_CURSOR_TABLE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, next, NULL);
+ CURSOR_API_CALL(cursor, session, next, NULL);
cp = ctable->cg_cursors;
/* Split out the first next, it retrieves the random record. */
@@ -269,7 +269,7 @@ __curtable_prev(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
ctable = (WT_CURSOR_TABLE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, prev, NULL);
+ CURSOR_API_CALL(cursor, session, prev, NULL);
APPLY_CG(ctable, prev);
API_END(session);
@@ -288,7 +288,7 @@ __curtable_reset(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
ctable = (WT_CURSOR_TABLE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, reset, NULL);
+ CURSOR_API_CALL(cursor, session, reset, NULL);
APPLY_CG(ctable, reset);
API_END(session);
@@ -307,7 +307,7 @@ __curtable_search(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
ctable = (WT_CURSOR_TABLE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, search, NULL);
+ CURSOR_API_CALL(cursor, session, search, NULL);
APPLY_CG(ctable, search);
API_END(session);
@@ -328,7 +328,7 @@ __curtable_search_near(WT_CURSOR *cursor, int *exact)
int i;
ctable = (WT_CURSOR_TABLE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, search_near, NULL);
+ CURSOR_API_CALL(cursor, session, search_near, NULL);
cp = ctable->cg_cursors;
primary = *cp;
WT_ERR(primary->search_near(primary, exact));
@@ -358,7 +358,7 @@ __curtable_insert(WT_CURSOR *cursor)
int i;
ctable = (WT_CURSOR_TABLE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, insert, NULL);
+ CURSOR_UPDATE_API_CALL(cursor, session, insert, NULL);
cp = ctable->cg_cursors;
/*
@@ -387,7 +387,7 @@ __curtable_insert(WT_CURSOR *cursor)
}
APPLY_IDX(ctable, insert);
-err: API_END(session);
+err: CURSOR_UPDATE_API_END(session, ret);
return (ret);
}
@@ -404,7 +404,7 @@ __curtable_update(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
ctable = (WT_CURSOR_TABLE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, update, NULL);
+ CURSOR_UPDATE_API_CALL(cursor, session, update, NULL);
WT_ERR(__curtable_open_indices(ctable));
/*
* If the table has indices, first delete any old index keys, then
@@ -427,7 +427,7 @@ __curtable_update(WT_CURSOR *cursor)
WT_ERR(ret);
if (ctable->idx_cursors != NULL)
APPLY_IDX(ctable, insert);
-err: API_END(session);
+err: CURSOR_UPDATE_API_END(session, ret);
return (ret);
}
@@ -444,7 +444,7 @@ __curtable_remove(WT_CURSOR *cursor)
WT_SESSION_IMPL *session;
ctable = (WT_CURSOR_TABLE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, remove, NULL);
+ CURSOR_UPDATE_API_CALL(cursor, session, remove, NULL);
/* Find the old record so it can be removed from indices */
WT_ERR(__curtable_open_indices(ctable));
@@ -455,7 +455,7 @@ __curtable_remove(WT_CURSOR *cursor)
}
APPLY_CG(ctable, remove);
-err: API_END(session);
+err: CURSOR_UPDATE_API_END(session, ret);
return (ret);
}
@@ -598,7 +598,7 @@ __curtable_close(WT_CURSOR *cursor)
int i;
ctable = (WT_CURSOR_TABLE *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, close, NULL);
+ CURSOR_API_CALL(cursor, session, close, NULL);
for (i = 0, cp = (ctable)->cg_cursors;
i < WT_COLGROUPS(ctable->table); i++, cp++)
diff --git a/src/include/api.h b/src/include/api.h
index 1beccb5c45c..6b58e0abb16 100644
--- a/src/include/api.h
+++ b/src/include/api.h
@@ -293,12 +293,6 @@ struct __wt_connection_impl {
} \
} while (0)
-/* If an error is returned, mark that the transaction requires abort. */
-#define API_END_TXN_ERROR(s, ret) \
- API_END(s); \
- if ((ret) != 0 && (ret) != WT_NOTFOUND && (ret) != WT_DUPLICATE_KEY) \
- F_SET(&(s)->txn, TXN_ERROR)
-
/*
* If a session or connection method is about to return WT_NOTFOUND (some
* underlying object was not found), map it to ENOENT, only cursor methods
@@ -315,10 +309,38 @@ struct __wt_connection_impl {
#define SESSION_API_CALL(s, n, cfg, cfgvar) \
API_CALL(s, session, n, NULL, NULL, cfg, cfgvar);
-#define CURSOR_API_CALL_NOCONF(cur, s, n, bt) \
+#define CURSOR_API_CALL(cur, s, n, bt) \
(s) = (WT_SESSION_IMPL *)(cur)->session; \
API_CALL_NOCONF(s, cursor, n, cur, bt)
+/*
+ * When a cursor update starts, wrap in a transaction if necessary.
+ */
+#define CURSOR_UPDATE_API_CALL(cur, s, n, bt) do { \
+ int __autotxn = 0; \
+ CURSOR_API_CALL(cur, s, n, bt); \
+ __autotxn = F_ISSET(S2C(s), WT_CONN_TRANSACTIONAL) && \
+ !F_ISSET(&(s)->txn, TXN_RUNNING); \
+ if (__autotxn) \
+ WT_ERR(__wt_txn_begin((s), NULL))
+
+/*
+ * When a cursor update completes, either auto-commit or check for errors
+ * that require the enclosing transaction to roll back.
+ */
+#define CURSOR_UPDATE_API_END(s, ret) \
+ API_END(s); \
+ if (__autotxn) { \
+ if (ret == 0) \
+ ret = __wt_txn_commit((s), NULL); \
+ else \
+ (void)__wt_txn_rollback((s), NULL); \
+ } else if ((ret) != 0 && \
+ (ret) != WT_NOTFOUND && \
+ (ret) != WT_DUPLICATE_KEY) \
+ F_SET(&(s)->txn, TXN_ERROR); \
+} while (0)
+
/*******************************************
* Global variables.
*******************************************/
diff --git a/src/include/txn.i b/src/include/txn.i
index ce2e369e461..eee2bed2133 100644
--- a/src/include/txn.i
+++ b/src/include/txn.i
@@ -9,45 +9,6 @@ static inline void __wt_txn_read_first(WT_SESSION_IMPL *session);
static inline void __wt_txn_read_last(WT_SESSION_IMPL *session);
/*
- * __wt_txn_getid --
- * Get a transaction ID for a non-transactional operation.
- */
-static inline void
-__wt_txn_getid(WT_SESSION_IMPL *session)
-{
- WT_TXN *txn;
- WT_TXN_GLOBAL *txn_global;
- wt_txnid_t id;
-
- txn = &session->txn;
-
- if (F_ISSET(txn, TXN_RUNNING))
- return;
-
- /* If we already have the latest ID, keep using it. */
- id = txn->id;
- txn_global = &S2C(session)->txn_global;
- if (id + 1 == txn_global->current &&
- id != WT_TXN_NONE && id != WT_TXN_ABORTED)
- return;
-
- do {
- id = txn_global->current;
- } while (!WT_ATOMIC_CAS(txn_global->current, id, id + 1) ||
- id == WT_TXN_NONE || id == WT_TXN_ABORTED);
-
- txn->id = id;
-
- /*
- * We allocated a new transaction ID for updates without an explicit
- * transaction. To ensure that our previous updates are visible,
- * update our transaction context (if required).
- */
- __wt_txn_read_last(session);
- __wt_txn_read_first(session);
-}
-
-/*
* __wt_txn_modify --
* Mark a WT_UPDATE object modified by the current transaction.
*/
@@ -57,15 +18,13 @@ __wt_txn_modify(WT_SESSION_IMPL *session, wt_txnid_t *id)
WT_TXN *txn;
txn = &session->txn;
- if (F_ISSET(txn, TXN_RUNNING)) {
- if (txn->mod_count * sizeof(wt_txnid_t *) == txn->mod_alloc)
- WT_RET(__wt_realloc(session, &txn->mod_alloc,
- WT_MAX(10, 2 * txn->mod_count) *
- sizeof(wt_txnid_t *), &txn->mod));
- txn->mod[txn->mod_count++] = id;
- } else
- __wt_txn_getid(session);
+ WT_ASSERT(session, F_ISSET(txn, TXN_RUNNING));
+ if (txn->mod_count * sizeof(wt_txnid_t *) == txn->mod_alloc)
+ WT_RET(__wt_realloc(session, &txn->mod_alloc,
+ WT_MAX(10, 2 * txn->mod_count) *
+ sizeof(wt_txnid_t *), &txn->mod));
+ txn->mod[txn->mod_count++] = id;
*id = txn->id;
return (0);
}
@@ -80,16 +39,14 @@ __wt_txn_modify_ref(WT_SESSION_IMPL *session, WT_REF *ref)
WT_TXN *txn;
txn = &session->txn;
- if (F_ISSET(txn, TXN_RUNNING)) {
- if (txn->modref_count *
- sizeof(WT_REF *) == txn->modref_alloc)
- WT_RET(__wt_realloc(session, &txn->modref_alloc,
- WT_MAX(10, 2 * txn->modref_count) *
- sizeof(WT_REF *), &txn->modref));
- txn->modref[txn->modref_count++] = ref;
- } else
- __wt_txn_getid(session);
-
+ WT_ASSERT(session, F_ISSET(txn, TXN_RUNNING));
+ if (txn->modref_count *
+ sizeof(WT_REF *) == txn->modref_alloc)
+ WT_RET(__wt_realloc(session, &txn->modref_alloc,
+ WT_MAX(10, 2 * txn->modref_count) *
+ sizeof(WT_REF *), &txn->modref));
+
+ txn->modref[txn->modref_count++] = ref;
ref->txnid = txn->id;
return (0);
}
diff --git a/src/lsm/lsm_cursor.c b/src/lsm/lsm_cursor.c
index 46e892faf35..f619af0ef86 100644
--- a/src/lsm/lsm_cursor.c
+++ b/src/lsm/lsm_cursor.c
@@ -21,15 +21,17 @@
WT_LSM_CMP(s, lsm_tree, &(c1)->key, &(c2)->key, cmp)
/*
- * LSM API enter/leave: check that the cursor is in sync with the tree.
+ * LSM API enter: check that the cursor is in sync with the tree.
*/
#define WT_LSM_ENTER(clsm, cursor, session, n) \
clsm = (WT_CURSOR_LSM *)cursor; \
- CURSOR_API_CALL_NOCONF(cursor, session, n, NULL); \
+ CURSOR_API_CALL(cursor, session, n, NULL); \
WT_ERR(__clsm_enter(clsm))
-#define WT_LSM_END(clsm, session) \
- API_END(session)
+#define WT_LSM_UPDATE_ENTER(clsm, cursor, session, n) \
+ clsm = (WT_CURSOR_LSM *)cursor; \
+ CURSOR_UPDATE_API_CALL(cursor, session, n, NULL); \
+ WT_ERR(__clsm_enter(clsm))
static int __clsm_open_cursors(WT_CURSOR_LSM *);
static int __clsm_search(WT_CURSOR *);
@@ -263,7 +265,7 @@ __clsm_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp)
/* There's no need to sync with the LSM tree, avoid WT_LSM_ENTER. */
alsm = (WT_CURSOR_LSM *)a;
- CURSOR_API_CALL_NOCONF(a, session, compare, NULL);
+ CURSOR_API_CALL(a, session, compare, NULL);
/*
* Confirm both cursors refer to the same source and have keys, then
@@ -359,7 +361,7 @@ retry: /*
if ((ret = __clsm_get_current(session, clsm, 1, &deleted)) == 0 &&
deleted)
goto retry;
-err: WT_LSM_END(clsm, session);
+err: API_END(session);
return (ret);
}
@@ -440,7 +442,7 @@ retry: /*
if ((ret = __clsm_get_current(session, clsm, 0, &deleted)) == 0 &&
deleted)
goto retry;
-err: WT_LSM_END(clsm, session);
+err: API_END(session);
return (ret);
}
@@ -462,7 +464,7 @@ __clsm_reset(WT_CURSOR *cursor)
* we want to do is give up our position.
*/
clsm = (WT_CURSOR_LSM *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, reset, NULL);
+ CURSOR_API_CALL(cursor, session, reset, NULL);
if ((c = clsm->current) != NULL) {
ret = c->reset(c);
clsm->current = NULL;
@@ -512,7 +514,7 @@ __clsm_search(WT_CURSOR *cursor)
ret = WT_NOTFOUND;
done:
-err: WT_LSM_END(clsm, session);
+err: API_END(session);
if (ret == 0)
F_SET(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
else
@@ -616,7 +618,7 @@ __clsm_search_near(WT_CURSOR *cursor, int *exactp)
ret = WT_NOTFOUND;
done:
-err: WT_LSM_END(clsm, session);
+err: API_END(session);
if (ret == 0) {
c = clsm->current;
WT_TRET(c->get_key(c, &cursor->key));
@@ -722,7 +724,7 @@ __clsm_insert(WT_CURSOR *cursor)
WT_DECL_RET;
WT_SESSION_IMPL *session;
- WT_LSM_ENTER(clsm, cursor, session, insert);
+ WT_LSM_UPDATE_ENTER(clsm, cursor, session, insert);
WT_CURSOR_NEEDKEY(cursor);
WT_LSM_NEEDVALUE(cursor);
@@ -735,8 +737,7 @@ __clsm_insert(WT_CURSOR *cursor)
ret = __clsm_put(session, clsm, &cursor->key, &cursor->value);
-err: WT_LSM_END(clsm, session);
-
+err: CURSOR_UPDATE_API_END(session, ret);
return (ret);
}
@@ -751,7 +752,7 @@ __clsm_update(WT_CURSOR *cursor)
WT_DECL_RET;
WT_SESSION_IMPL *session;
- WT_LSM_ENTER(clsm, cursor, session, update);
+ WT_LSM_UPDATE_ENTER(clsm, cursor, session, update);
WT_CURSOR_NEEDKEY(cursor);
WT_LSM_NEEDVALUE(cursor);
@@ -759,8 +760,7 @@ __clsm_update(WT_CURSOR *cursor)
(ret = __clsm_search(cursor)) == 0)
ret = __clsm_put(session, clsm, &cursor->key, &cursor->value);
-err: WT_LSM_END(clsm, session);
-
+err: CURSOR_UPDATE_API_END(session, ret);
return (ret);
}
@@ -775,15 +775,14 @@ __clsm_remove(WT_CURSOR *cursor)
WT_DECL_RET;
WT_SESSION_IMPL *session;
- WT_LSM_ENTER(clsm, cursor, session, remove);
+ WT_LSM_UPDATE_ENTER(clsm, cursor, session, remove);
WT_CURSOR_NEEDKEY(cursor);
if (F_ISSET(cursor, WT_CURSTD_OVERWRITE) ||
(ret = __clsm_search(cursor)) == 0)
ret = __clsm_put(session, clsm, &cursor->key, &__lsm_tombstone);
-err: WT_LSM_END(clsm, session);
-
+err: CURSOR_UPDATE_API_END(session, ret);
return (ret);
}
@@ -803,7 +802,7 @@ __clsm_close(WT_CURSOR *cursor)
* closing, and the cursor may never have been used.
*/
clsm = (WT_CURSOR_LSM *)cursor;
- CURSOR_API_CALL_NOCONF(cursor, session, close, NULL);
+ CURSOR_API_CALL(cursor, session, close, NULL);
WT_TRET(__clsm_close_cursors(clsm));
__wt_free(session, clsm->blooms);
__wt_free(session, clsm->cursors);
diff --git a/src/txn/txn.c b/src/txn/txn.c
index a135c57d6c1..9cb0255767e 100644
--- a/src/txn/txn.c
+++ b/src/txn/txn.c
@@ -166,8 +166,6 @@ __wt_txn_begin(WT_SESSION_IMPL *session, const char *cfg[])
WT_STRING_MATCH("read-committed", cval.str, cval.len) ?
TXN_ISO_READ_COMMITTED : TXN_ISO_READ_UNCOMMITTED;
- WT_ASSERT(session, session->ncursors == 0);
-
F_SET(txn, TXN_RUNNING);
do {