Skip to content

Commit a7d4aba

Browse files
committed
Fix bcit-ci#4171 and a number of other transaction bugs
1 parent 95f8157 commit a7d4aba

File tree

15 files changed

+170
-356
lines changed

15 files changed

+170
-356
lines changed

system/database/DB_driver.php

Lines changed: 91 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,13 @@ public function query($sql, $binds = FALSE, $return_object = NULL)
668668
{
669669
do
670670
{
671+
$trans_depth = $this->_trans_depth;
671672
$this->trans_complete();
673+
if ($trans_depth === $this->_trans_depth)
674+
{
675+
log_message('error', 'Database: Failure during an automated transaction commit/rollback!');
676+
break;
677+
}
672678
}
673679
while ($this->_trans_depth !== 0);
674680
}
@@ -813,24 +819,16 @@ public function trans_strict($mode = TRUE)
813819
* Start Transaction
814820
*
815821
* @param bool $test_mode = FALSE
816-
* @return void
822+
* @return bool
817823
*/
818824
public function trans_start($test_mode = FALSE)
819825
{
820826
if ( ! $this->trans_enabled)
821827
{
822-
return;
823-
}
824-
825-
// When transactions are nested we only begin/commit/rollback the outermost ones
826-
if ($this->_trans_depth > 0)
827-
{
828-
$this->_trans_depth += 1;
829-
return;
828+
return FALSE;
830829
}
831830

832-
$this->trans_begin($test_mode);
833-
$this->_trans_depth += 1;
831+
return $this->trans_begin($test_mode);
834832
}
835833

836834
// --------------------------------------------------------------------
@@ -847,17 +845,6 @@ public function trans_complete()
847845
return FALSE;
848846
}
849847

850-
// When transactions are nested we only begin/commit/rollback the outermost ones
851-
if ($this->_trans_depth > 1)
852-
{
853-
$this->_trans_depth -= 1;
854-
return TRUE;
855-
}
856-
else
857-
{
858-
$this->_trans_depth = 0;
859-
}
860-
861848
// The query() function will set this flag to FALSE in the event that a query failed
862849
if ($this->_trans_status === FALSE OR $this->_trans_failure === TRUE)
863850
{
@@ -875,8 +862,7 @@ public function trans_complete()
875862
return FALSE;
876863
}
877864

878-
$this->trans_commit();
879-
return TRUE;
865+
return $this->trans_commit();
880866
}
881867

882868
// --------------------------------------------------------------------
@@ -893,6 +879,87 @@ public function trans_status()
893879

894880
// --------------------------------------------------------------------
895881

882+
/**
883+
* Begin Transaction
884+
*
885+
* @param bool $test_mode
886+
* @return bool
887+
*/
888+
public function trans_begin($test_mode = FALSE)
889+
{
890+
if ( ! $this->trans_enabled)
891+
{
892+
return FALSE;
893+
}
894+
// When transactions are nested we only begin/commit/rollback the outermost ones
895+
elseif ($this->_trans_depth > 0)
896+
{
897+
$this->_trans_depth++;
898+
return TRUE;
899+
}
900+
901+
// Reset the transaction failure flag.
902+
// If the $test_mode flag is set to TRUE transactions will be rolled back
903+
// even if the queries produce a successful result.
904+
$this->_trans_failure = ($test_mode === TRUE);
905+
906+
if ($this->_trans_begin())
907+
{
908+
$this->_trans_depth++;
909+
return TRUE;
910+
}
911+
912+
return FALSE;
913+
}
914+
915+
// --------------------------------------------------------------------
916+
917+
/**
918+
* Commit Transaction
919+
*
920+
* @return bool
921+
*/
922+
public function trans_commit()
923+
{
924+
if ( ! $this->trans_enabled OR $this->_trans_depth === 0)
925+
{
926+
return FALSE;
927+
}
928+
// When transactions are nested we only begin/commit/rollback the outermost ones
929+
elseif ($this->_trans_depth > 1 OR $this->_trans_commit())
930+
{
931+
$this->_trans_depth--;
932+
return TRUE;
933+
}
934+
935+
return FALSE;
936+
}
937+
938+
// --------------------------------------------------------------------
939+
940+
/**
941+
* Rollback Transaction
942+
*
943+
* @return bool
944+
*/
945+
public function trans_rollback()
946+
{
947+
if ( ! $this->trans_enabled OR $this->_trans_depth === 0)
948+
{
949+
return FALSE;
950+
}
951+
// When transactions are nested we only begin/commit/rollback the outermost ones
952+
elseif ($this->_trans_depth > 1 OR $this->_trans_rollback())
953+
{
954+
$this->_trans_depth--;
955+
return TRUE;
956+
}
957+
958+
return FALSE;
959+
}
960+
961+
// --------------------------------------------------------------------
962+
896963
/**
897964
* Compile Bindings
898965
*

system/database/drivers/cubrid/cubrid_driver.php

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -187,25 +187,17 @@ protected function _execute($sql)
187187
/**
188188
* Begin Transaction
189189
*
190-
* @param bool $test_mode
191190
* @return bool
192191
*/
193-
public function trans_begin($test_mode = FALSE)
192+
protected function _trans_begin()
194193
{
195-
// When transactions are nested we only begin/commit/rollback the outermost ones
196-
if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
194+
if (($autocommit = cubrid_get_autocommit($this->conn_id)) === NULL)
197195
{
198-
return TRUE;
196+
return FALSE;
199197
}
200-
201-
// Reset the transaction failure flag.
202-
// If the $test_mode flag is set to TRUE transactions will be rolled back
203-
// even if the queries produce a successful result.
204-
$this->_trans_failure = ($test_mode === TRUE);
205-
206-
if (cubrid_get_autocommit($this->conn_id))
198+
elseif ($autocommit === TRUE)
207199
{
208-
cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_FALSE);
200+
return cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_FALSE);
209201
}
210202

211203
return TRUE;
@@ -218,19 +210,16 @@ public function trans_begin($test_mode = FALSE)
218210
*
219211
* @return bool
220212
*/
221-
public function trans_commit()
213+
protected function _trans_commit()
222214
{
223-
// When transactions are nested we only begin/commit/rollback the outermost ones
224-
if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
215+
if ( ! cubrid_commit($this->conn_id))
225216
{
226-
return TRUE;
217+
return FALSE;
227218
}
228219

229-
cubrid_commit($this->conn_id);
230-
231220
if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id))
232221
{
233-
cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE);
222+
return cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE);
234223
}
235224

236225
return TRUE;
@@ -243,16 +232,13 @@ public function trans_commit()
243232
*
244233
* @return bool
245234
*/
246-
public function trans_rollback()
235+
protected function _trans_rollback()
247236
{
248-
// When transactions are nested we only begin/commit/rollback the outermost ones
249-
if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
237+
if ( ! cubrid_rollback($this->conn_id))
250238
{
251-
return TRUE;
239+
return FALSE;
252240
}
253241

254-
cubrid_rollback($this->conn_id);
255-
256242
if ($this->auto_commit && ! cubrid_get_autocommit($this->conn_id))
257243
{
258244
cubrid_set_autocommit($this->conn_id, CUBRID_AUTOCOMMIT_TRUE);

system/database/drivers/ibase/ibase_driver.php

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -134,24 +134,16 @@ protected function _execute($sql)
134134
/**
135135
* Begin Transaction
136136
*
137-
* @param bool $test_mode
138137
* @return bool
139138
*/
140-
public function trans_begin($test_mode = FALSE)
139+
protected function _trans_begin()
141140
{
142-
// When transactions are nested we only begin/commit/rollback the outermost ones
143-
if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
141+
if (($trans_handle = ibase_trans($this->conn_id)) === FALSE)
144142
{
145-
return TRUE;
143+
return FALSE;
146144
}
147145

148-
// Reset the transaction failure flag.
149-
// If the $test_mode flag is set to TRUE transactions will be rolled back
150-
// even if the queries produce a successful result.
151-
$this->_trans_failure = ($test_mode === TRUE);
152-
153-
$this->_ibase_trans = ibase_trans($this->conn_id);
154-
146+
$this->_ibase_trans = $trans_handle;
155147
return TRUE;
156148
}
157149

@@ -162,15 +154,15 @@ public function trans_begin($test_mode = FALSE)
162154
*
163155
* @return bool
164156
*/
165-
public function trans_commit()
157+
protected function _trans_commit()
166158
{
167-
// When transactions are nested we only begin/commit/rollback the outermost ones
168-
if ( ! $this->trans_enabled OR $this->_trans->depth > 0)
159+
if (ibase_commit($this->_ibase_trans))
169160
{
161+
$this->_ibase_trans = NULL;
170162
return TRUE;
171163
}
172164

173-
return ibase_commit($this->_ibase_trans);
165+
return FALSE;
174166
}
175167

176168
// --------------------------------------------------------------------
@@ -180,15 +172,15 @@ public function trans_commit()
180172
*
181173
* @return bool
182174
*/
183-
public function trans_rollback()
175+
protected function _trans_rollback()
184176
{
185-
// When transactions are nested we only begin/commit/rollback the outermost ones
186-
if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
177+
if (ibase_rollback($this->_ibase_trans))
187178
{
179+
$this->_ibase_trans = NULL;
188180
return TRUE;
189181
}
190182

191-
return ibase_rollback($this->_ibase_trans);
183+
return FALSE;
192184
}
193185

194186
// --------------------------------------------------------------------

system/database/drivers/mssql/mssql_driver.php

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -182,22 +182,10 @@ protected function _execute($sql)
182182
/**
183183
* Begin Transaction
184184
*
185-
* @param bool $test_mode
186185
* @return bool
187186
*/
188-
public function trans_begin($test_mode = FALSE)
187+
protected function _trans_begin()
189188
{
190-
// When transactions are nested we only begin/commit/rollback the outermost ones
191-
if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
192-
{
193-
return TRUE;
194-
}
195-
196-
// Reset the transaction failure flag.
197-
// If the $test_mode flag is set to TRUE transactions will be rolled back
198-
// even if the queries produce a successful result.
199-
$this->_trans_failure = ($test_mode === TRUE);
200-
201189
return $this->simple_query('BEGIN TRAN');
202190
}
203191

@@ -208,14 +196,8 @@ public function trans_begin($test_mode = FALSE)
208196
*
209197
* @return bool
210198
*/
211-
public function trans_commit()
199+
protected function _trans_commit()
212200
{
213-
// When transactions are nested we only begin/commit/rollback the outermost ones
214-
if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
215-
{
216-
return TRUE;
217-
}
218-
219201
return $this->simple_query('COMMIT TRAN');
220202
}
221203

@@ -226,14 +208,8 @@ public function trans_commit()
226208
*
227209
* @return bool
228210
*/
229-
public function trans_rollback()
211+
protected function _trans_rollback()
230212
{
231-
// When transactions are nested we only begin/commit/rollback the outermost ones
232-
if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
233-
{
234-
return TRUE;
235-
}
236-
237213
return $this->simple_query('ROLLBACK TRAN');
238214
}
239215

0 commit comments

Comments
 (0)