From: Janusz Dobrowolski Date: Tue, 9 Feb 2010 13:10:02 +0000 (+0000) Subject: Improved transactions support (multilevel). X-Git-Tag: v2.4.2~19^2~955 X-Git-Url: https://delta.frontaccounting.com/gitweb/?a=commitdiff_plain;h=aa3baa1fadd3c56034dbe371ae864bc0346b3c4d;p=fa-stable.git Improved transactions support (multilevel). --- diff --git a/includes/db/connect_db.inc b/includes/db/connect_db.inc index 203883b0..3e0d551f 100644 --- a/includes/db/connect_db.inc +++ b/includes/db/connect_db.inc @@ -12,7 +12,10 @@ function set_global_connection() { - global $db; + global $db, $transaction_level; + + cancel_transaction(); // cancel all aborted transactions if any + $transaction_level = 0; $db = $_SESSION["wa_current_user"]->get_db_connection(); } diff --git a/includes/db/sql_functions.inc b/includes/db/sql_functions.inc index 0fa479dc..2e5a28f4 100644 --- a/includes/db/sql_functions.inc +++ b/includes/db/sql_functions.inc @@ -12,21 +12,51 @@ // // General database functions common for all modules. // -//------------------------------------------------------------------- +//------------------------------------------------------------------- +// Multilevel transaction control. +// + function begin_transaction() { - db_query("BEGIN", "could not start a transaction"); + global $transaction_level; // set in set_global_connection() + + if (!$transaction_level) { + error_log('begin'); + db_query("BEGIN", "could not start a transaction"); + } + $transaction_level++; + error_log("level:$transaction_level"); } function commit_transaction() { - db_query("COMMIT", "could not commit a transaction"); + global $transaction_level; + + $transaction_level--; + + if (!$transaction_level) { + error_log('commit'); + db_query("COMMIT", "could not commit a transaction"); + } + error_log("level:$transaction_level"); } +/* + This function is called on end of script execution to cancel + all aborted transactions (if any) +*/ function cancel_transaction() { - db_query("ROLLBACK", "could not cancel a transaction"); + global $transaction_level; + + if ($transaction_level) { + error_log('rollback'); + db_query("ROLLBACK", "could not cancel a transaction"); + } else + error_log("no transactions"); + } + //----------------------------------------------------------------------------- // Update record activity status. // diff --git a/includes/errors.inc b/includes/errors.inc index 551d32e4..9e0dba2e 100644 --- a/includes/errors.inc +++ b/includes/errors.inc @@ -94,13 +94,16 @@ function error_box() { /* Helper to avoid sparse log notices. */ -function end_flush () { - global $Ajax; +function end_flush() { + global $Ajax, $transaction_level; if (isset($Ajax)) $Ajax->run(); // flush all output buffers (works also with exit inside any div levels) while(ob_get_level()) ob_end_flush(); + + // if any transaction was aborted unexpectedly rollback changes + cancel_transaction(); } function display_db_error($msg, $sql_statement=null, $exit=true) diff --git a/sales/includes/cart_class.inc b/sales/includes/cart_class.inc index 68166e98..3566d686 100644 --- a/sales/includes/cart_class.inc +++ b/sales/includes/cart_class.inc @@ -209,6 +209,7 @@ class cart // Makes parent documents for direct delivery/invoice by recurent call. // $policy - 0 or 1: writeoff/return for IV, back order/cancel for DN function write($policy=0) { + begin_transaction(); // prevents partial database changes in case of direct delivery/invoice if (count($this->src_docs) == 0 && ($this->trans_type == ST_SALESINVOICE || $this->trans_type == ST_CUSTDELIVERY)) { // this is direct document - first add parent $src = (PHP_VERSION<5) ? $this : clone( $this ); // make local copy of this cart @@ -236,18 +237,20 @@ class cart } switch($this->trans_type) { case ST_SALESINVOICE: - return write_sales_invoice($this); + write_sales_invoice($this); break; case ST_CUSTCREDIT: - return write_credit_note($this, $policy); + write_credit_note($this, $policy); break; case ST_CUSTDELIVERY: - return write_sales_delivery($this, $policy); + write_sales_delivery($this, $policy); break; case ST_SALESORDER: case ST_SALESQUOTE: if ($this->trans_no==0) // new document - return add_sales_order($this); + add_sales_order($this); else - return update_sales_order($this); + update_sales_order($this); } + + commit_transaction(); } function set_customer($customer_id, $customer_name, $currency, $discount, $payment, $cdiscount=0)