From a1f583177e3da754f9b9bdfb09219133f110de86 Mon Sep 17 00:00:00 2001 From: Tilghman Lesher Date: Thu, 19 Feb 2009 00:26:01 +0000 Subject: ODBC transaction support git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@177320 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- funcs/func_odbc.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'funcs') diff --git a/funcs/func_odbc.c b/funcs/func_odbc.c index d56a1df27..fb733a421 100644 --- a/funcs/func_odbc.c +++ b/funcs/func_odbc.c @@ -2,6 +2,7 @@ * Asterisk -- An open source telephony toolkit. * * Copyright (c) 2005, 2006 Tilghman Lesher + * Copyright (c) 2008 Digium, Inc. * * Tilghman Lesher * @@ -205,6 +206,7 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co struct acf_odbc_query *query; char *t, varname[15]; int i, dsn, bogus_chan = 0; + int transactional = 0; AST_DECLARE_APP_ARGS(values, AST_APP_ARG(field)[100]; ); @@ -293,16 +295,32 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co } pbx_builtin_setvar_helper(chan, "VALUE", NULL); + /*!\note + * Okay, this part is confusing. Transactions belong to a single database + * handle. Therefore, when working with transactions, we CANNOT failover + * to multiple DSNs. We MUST have a single handle all the way through the + * transaction, or else we CANNOT enforce atomicity. + */ for (dsn = 0; dsn < 5; dsn++) { + if (transactional) { + /* This can only happen second time through or greater. */ + ast_log(LOG_WARNING, "Transactions do not work well with multiple DSNs for 'writehandle'\n"); + } + if (!ast_strlen_zero(query->writehandle[dsn])) { - obj = ast_odbc_request_obj(query->writehandle[dsn], 0); - if (obj) - stmt = ast_odbc_direct_execute(obj, generic_execute, ast_str_buffer(buf)); + if ((obj = ast_odbc_retrieve_transaction_obj(chan, query->writehandle[dsn]))) { + transactional = 1; + } else { + obj = ast_odbc_request_obj(query->writehandle[dsn], 0); + transactional = 0; + } + if (obj && (stmt = ast_odbc_direct_execute(obj, generic_execute, ast_str_buffer(buf)))) { + break; + } } - if (stmt) { - status = "SUCCESS"; - SQLRowCount(stmt, &rows); - break; + + if (obj && !transactional) { + ast_odbc_release_obj(obj); } } @@ -322,6 +340,9 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co break; } } + } else if (stmt) { + status = "SUCCESS"; + SQLRowCount(stmt, &rows); } AST_RWLIST_UNLOCK(&queries); @@ -338,7 +359,7 @@ static int acf_odbc_write(struct ast_channel *chan, const char *cmd, char *s, co SQLCloseCursor(stmt); SQLFreeHandle(SQL_HANDLE_STMT, stmt); } - if (obj) { + if (obj && !transactional) { ast_odbc_release_obj(obj); obj = NULL; } -- cgit v1.2.3