as there are two possible way to implement transactions in codeigniter:
1.automatic
2.manual
I am getting an error like :Lock_wait_timeout in my codeigniter application.I don't have any wrong query in my code.But i found that i have wrote transaction code for automatic transaction similar to manual transaction.
as automatic transaction uses trans_start() ,on the other hand manual transaction uses trans_begin().
For manual transaction codeigniter uses the following syntax
$this->db->trans_begin();
insert query...
update query...
if($this->db->trans_status()===FALSE){
$this->db->trans_rollback();
}else{
$this->db->trans_commit();
}
But i have used automatic transaction in my code,and wrote it like the following(used if else statement like manual transaction):
$this->db->trans_start();
insert query...
update query...
$this->db->trans_complete();
if($this->db->trans_status()===FALSE){
$this->db->trans_rollback();
}else{
$this->db->trans_commit();
}
The function trans_complete() does almost exactly the same thing as your if/else statement as it makes a call to either trans_rollback() or trans_commit() as appropriate. Undoubtedly your second attempt at commit or rollback is greatly confusing your database. Just remove your if/else and all should be good.
Related
Below is the syntax from a Model using Codeigniter Framework. So i want to do this kind of query, i grouped many query inside another class like this, but i used this transaction outside the class like this.
$this->db->trans_begin();
$insert1 = $this->Actmain->tempPerwakilanToTransaksi($t_nib_kppa_temp['id_permohonan']);
$insert2 = $this->Actmain->transaksiPerwakilanToHistory($t_nib_kppa_temp['id_permohonan'],$arrData['id_history']);
if(!$insert1 || !$insert2) {
$this->db->trans_rollback();
return FALSE;
} else {
$this->db->trans_commit();
echo "Yatta desune"
}
I want to check if at least one query that didn't work successfully, it will rollback all the query. The problem is, it's always return true which came from query in variable $insert1 or $insert2. It's always echo Yatta Desune but the insert and update query didn't executed.
What is the proper way to used db transaction in Codeigniter 3 but bunch of query executed in different Model ?
I do seem to be having problems getting database transactions to work on a model. I've referred to related posts on SO, but no luck yet.
In my example, I create a new record in the DB. I should be able to rollback and the new record should have disappeared shouldn't it?
try{
DB::beginTransaction();
$oNewMap = $oMap->replicate();
$oNewMap->name = "[test] " . $oNewMap->name;
$oNewMap->save(); // works
DB::rollBack(); / /record still in db
}
catch(\Exception $e){
DB::rollBack();
/* Transaction failed. */
}
When the rollback occured, why wouldn't the saved record disappear from the DB? Am I missing something with how models work with transactions?
The physical tables are all InnoDB, btw.
[EDITTED: to simplify the problem to a simple save and rollback, not doing two saves where the second save violates an FK constraint.]
If the model doesn't use the default database connection, you have to specify it on the transaction:
DB::connection('name')->beginTransaction();
DB::connection('name')->commit();
DB::connection('name')->rollBack();
Seeing your question, i remember a long time ago, where I had the same problem.
In the end i found out, that the function is called rollBack and not rollback - Note the capitalized B
Check your transaction level and conform that you are working with single beginTransaction() so, might you will find solution perfectly.
DB::beginTransaction()
DB::beginTransaction()
DB::transactionLevel() // will return 2
DB::commit() // doesn't commit
DB::transactionLevel() // will return 1
DB::commit() // finally, it commits to the database
DB::transactionLevel() // will return 0
I'm trying to use transaction when creating table group, and table with relation user-group.
It works ok when I don't use transaction, so the naming of the attributes is correct. Here is the code:
$db = Yii::app()->db;
$transaction = $db->beginTransaction();
try {
$model->attributes=$_POST['MyGroup'];
$model->save();
$model->refresh();
$userMyGroup = new UserMyGroup();
$userMyGroup->IDMyGroup = $model->IDMyGroup;
$userMyGroup->IDUser = Yii::app()->user->id;
$userMyGroup->save();
$transaction->commit();
} catch (CDbException $ex) {
Yii::log("Couldn't create group:".$ex->errorInfo[1], CLogger::LEVEL_ERROR);
$transaction->rollback();
}
The error is:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_UserMyGroup_MyGroup". The conflict occurred in database "MyDatabase", table "dbo.MyGroup", column 'IDMyGroup'.. The SQL statement executed was: INSERT INTO [dbo].[UserMyGroup] ([IDMyGroup], [IDUser]) VALUES (:yp0, :yp1). Bound with :yp0=4022, :yp1=1
Problem is probably that the saved model might not be in database while saving the second model(userMyGroup) with the foreign key. How to do the transaction correctly?
EDIT:
I've found out that the problem is caused by audit module, it is trying to log the query, but can't as it is in transaction and not really saved yet in database. I'm trying to figure out how to use this transaction along with the module...
The refresh method repopulates active record with the latest data.
While transaction is not commited latest data is existing data in table.
Move $model->refresh(); after $transaction->commit();
I've found out that the problem is caused by audit module which I'm using, it is trying to log the query, but can't as it is in transaction and not really saved yet in database. Unfortunately, I didn't figure out how to use this transaction along with the module, so the result is to disable audit module on the classes used in transaction.
I am calling multiple models in controllers and all models do database query.
i did something like this
public function InsertSale()
{
$this->db->trans_start(TRUE);
// all logic part and models calling which do insert/update/delete
$this->db->trans_complete();
}
Above code is not working even if something fails after some queries they dont rollback.
Having true in $this->db->trans_start(true); will put the transaction in to test mode which means that, regardless of what happens, the query will be rolled back.
If you wanted to see if the query would work you would use:
$this->db->trans_status();
Which will return either true/false depending on the outcome.
So that you have to follow like this
$this->db->trans_start(); # Starting Transaction
$this->db->trans_strict(FALSE);
$this->db->insert('table_name', $someDataArray); # Inserting data
# Updating data
$this->db->where('id', $id);
$this->db->update('table_name', $someDataArray);
$this->db->trans_complete();
This is work fine. Check this answer too
I'm trying to execute a DROP TEMPORARY TABLE statement. I've run the statement using MySQL Workbench and it works there. I've made sure I'm successfully logged in as the same user in both PHP and MySQL Workbench.
I've tried using both mysqli::query() and mysqli::prepare then mysqli::execute() methods. Neither works when I try to execute the DROP TEMPORARY TABLE statement. However, both work when I execute either an INSERT or SELECT statement.
This code doesn't return error, but also doesn't execute in the database:
public function executeSQL()
{
// SQL statement using query method
if (!$this->mySQLi->query("DROP TEMPORARY TABLE IF EXISTS TIME_INTERVAL_DATA") )
{
$this->writeSQLErrorToLog("Query method returned an error.");
}
if(!$this->mySQLi->commit())
{
// Committing the transaction failed.
$this->writeSQLErrorToLog("Commit method returned an error.");
}
// SQL statement using prepare and execute methods
$stmt = $this->mySQLi->prepare("DROP TEMPORARY TABLE IF EXISTS TIME_INTERVAL_DATA");
if($stmt)
{
if(!$stmt->execute())
{
// Execute method returned an error.
$this->writeSQLErrorToLog("Execute method returned an error.");
$this->throwMySQLErrorAndCloseStatement($stmt);
}
} else {
// Prepare method returned an error.
$this->writeSQLErrorToLog("Prepare method returned an error.");
return;
}
// ...
}
However, the following code does execute in the database:
$stmt = $this->mySQLi->prepare("INSERT INTO TABLE1 (ID) VALUES (1)");
if(!$stmt->execute()) {
// Return the MySQL Error message and number
$this->throwMySQLErrorAndCloseStatement($stmt);
}
I've been reading as many of the MySQL and PHP docs as I can find. I've read and re-read the docs on all of the above mysqli methods. And I've read about and tried variations of using mysqli::escape_string(), but when I use it an error is returned. I've also tried many variations of different SQL statements.
In a nutshell, all of the INSERT and SELECT statements work. But, the DROP TEMPORARY TABLE statement never works and never returns an error. I'm really scratching my head on this one. Any help would be much appreciated!!