1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-27 03:21:53 +03:00

s4-ldb: expose ldb_transaction_prepare_commit() in ldb

It is useful to be able to control the 2 phase commit from application
code (s4 replication uses it)
This commit is contained in:
Andrew Tridgell 2009-09-15 14:07:06 -07:00
parent bfd0877261
commit 08f144777d
3 changed files with 64 additions and 21 deletions

View File

@ -316,6 +316,7 @@ int ldb_transaction_start(struct ldb_context *ldb)
/* start a new transaction */
ldb->transaction_active++;
ldb->prepare_commit_done = false;
FIRST_OP(ldb, start_transaction);
@ -334,6 +335,57 @@ int ldb_transaction_start(struct ldb_context *ldb)
return status;
}
/*
prepare for transaction commit (first phase of two phase commit)
*/
int ldb_transaction_prepare_commit(struct ldb_context *ldb)
{
struct ldb_module *module;
int status;
if (ldb->prepare_commit_done) {
return LDB_SUCCESS;
}
/* commit only when all nested transactions are complete */
if (ldb->transaction_active > 1) {
return LDB_SUCCESS;
}
ldb->prepare_commit_done = true;
if (ldb->transaction_active < 0) {
ldb_debug(ldb, LDB_DEBUG_FATAL,
"prepare commit called but no ldb transactions are active!");
ldb->transaction_active = 0;
return LDB_ERR_OPERATIONS_ERROR;
}
/* call prepare transaction if available */
FIRST_OP_NOERR(ldb, prepare_commit);
if (module == NULL) {
return LDB_SUCCESS;
}
status = module->ops->prepare_commit(module);
if (status != LDB_SUCCESS) {
/* if a module fails the prepare then we need
to call the end transaction for everyone */
FIRST_OP(ldb, end_transaction);
module->ops->end_transaction(module);
if (ldb->err_string == NULL) {
/* no error string was setup by the backend */
ldb_asprintf_errstring(ldb,
"ldb transaction prepare commit: %s (%d)",
ldb_strerror(status),
status);
}
}
return status;
}
/*
commit a transaction
*/
@ -342,6 +394,10 @@ int ldb_transaction_commit(struct ldb_context *ldb)
struct ldb_module *module;
int status;
status = ldb_transaction_prepare_commit(ldb);
if (status != LDB_SUCCESS) {
return status;
}
ldb->transaction_active--;
@ -361,27 +417,6 @@ int ldb_transaction_commit(struct ldb_context *ldb)
return LDB_ERR_OPERATIONS_ERROR;
}
/* call prepare transaction if available */
FIRST_OP_NOERR(ldb, prepare_commit);
if (module != NULL) {
status = module->ops->prepare_commit(module);
if (status != LDB_SUCCESS) {
/* if a module fails the prepare then we need
to call the end transaction for everyone */
/* preserve err string */
FIRST_OP(ldb, end_transaction);
module->ops->end_transaction(module);
if (ldb->err_string == NULL) {
/* no error string was setup by the backend */
ldb_asprintf_errstring(ldb,
"ldb transaction prepare commit: %s (%d)",
ldb_strerror(status),
status);
}
return status;
}
}
ldb_reset_err_string(ldb);
FIRST_OP(ldb, end_transaction);
@ -401,6 +436,7 @@ int ldb_transaction_commit(struct ldb_context *ldb)
return status;
}
/*
cancel a transaction
*/

View File

@ -1283,6 +1283,11 @@ int ldb_sequence_number(struct ldb_context *ldb, enum ldb_sequence_type type, ui
*/
int ldb_transaction_start(struct ldb_context *ldb);
/**
first phase of two phase commit
*/
int ldb_transaction_prepare_commit(struct ldb_context *ldb);
/**
commit a transaction
*/

View File

@ -114,6 +114,8 @@ struct ldb_context {
char *modules_dir;
struct tevent_context *ev_ctx;
bool prepare_commit_done;
};
/* The following definitions come from lib/ldb/common/ldb.c */