I am trying to update 3 tables using transaction if any one fails I need to roll back all the tables. For one table foreign key constraint fails but it does not return false statement instead showing console error of Database. Roll back is working. I include my code below. Kindly help.
The function below helps me to execute some queries
function funcname($val1,$val2,$val3){
$this->db->trans_start();//starting transaction
try { // trying to execute query
$this->db->query("UPDATE tab1 SET name = 1 WHERE id=".$val1);
$this->db->query("UPDATE school SET emp = 2 WHERE id=".$val2);
$this->db->query("UPDATE profile SET status = 4 WHERE id=".$val3);
$this->db->trans_complete();
return TRUE;
} catch (Exception $ex) { //exception roll back to original state
$this->db->trans_rollback();
return FALSE;
}
}
If you are using trans_start() and trans_complete() then you need not use a try catch statement. Your function will be like this.
function funcname($val1,$val2,$val3){
$this->db->trans_start();//starting transaction
$this->db->query("UPDATE tab1 SET name = 1 WHERE id=".$val1);
$this->db->query("UPDATE school SET emp = 2 WHERE id=".$val2);
$this->db->query("UPDATE profile SET status = 4 WHERE id=".$val3);
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
return FALSE;
}
else
{
return TRUE;
}
}
In case you need to do it manually then use the code below
function funcname($val1,$val2,$val3){
$this->db->trans_begin();//starting transaction
$this->db->query("UPDATE tab1 SET name = 1 WHERE id=".$val1);
$this->db->query("UPDATE school SET emp = 2 WHERE id=".$val2);
$this->db->query("UPDATE profile SET status = 4 WHERE id=".$val3);
if ($this->db->trans_status() === FALSE)
{
$this->db->trans_rollback();
return FALSE;
}
else
{
$this->db->trans_commit();
return TRUE;
}
}
for more reference Transactions : CodeIgniter User Guide
I don't know how your db class works, but probably query return false on fails not throw Exception, so trans_complete() return false too, and then your function return TRUE
Related
So i'm trying to run an query by using a transaction but it's not working somehow i did check all the posts but no fixes seems to be working ! whenever i remove the transaction the insert query works just fine.
Here's the controller :
public function addEmployee(){
$field = array(
'NomClient'=>$this->input->post('fullName'),
'TelClient'=>$this->input->post('tel'),
'WilayaClient'=>$this->input->post('wilaya'),
'CommuneClient'=>$this->input->post('commune'),
'AdresseClient'=>$this->input->post('adresse'),
'StatusID'=>$this->input->post('statusCommande'),
'TelevendeuseID'=>$this->input->post('televendeuse')
);
$result= $this->m->addEmployee($field);
$msg['success'] = false;
$msg['type'] = 'add';
if($result){
$msg['success'] = true;
}
echo json_encode($msg);
}
My model :
public function addEmployee($field){
$this->db->trans_start();
return $this->db->insert('Clients',$field);
$this->db->trans_complete();
}
Please note that when i switch the model to :
public function addEmployee($field){
return $this->db->insert('Clients',$field);
}
The record gets inserted successfully ! Which means that something is wrong with the transaction. I'm currently using one query to test if it's working so i can use multiples onces after that. Note that the tables are InnoDB tables so the problem isn't with the table type. Please help me out !
When you call return it will end the function, so when it hits
return $this->db->insert('Clients',$field);
it will not get to
$this->db->trans_complete();
so perhaps...
$this->db->trans_start();
$return = $this->db->insert('Clients',$field);
$this->db->trans_complete();
return $return;
In my first table(ts_users) update opening user_opening_balance at the same time, I want to update that user_opening_balance in my second table(ts_voucher) column is voucher_amount. But in my second table table(ts_voucher) voucher_amount updates all columns amount.
My code:
public function updateConsignor($myData){
extract($myData);
$this->db->set('user_full_name' , $user_full_name);
$this->db->set('user_opening_balance' , $user_opening_balance);
$this->db->where('user_id', $user_id);
if($this->db->update('ts_users')){
$userId = $myData['user_id'];
$this->db->trans_begin();
$openingBalTrxn = array(
'voucher_amount' => $myData['user_opening_balance'],
);
$this->db->update('ts_voucher', $openingBalTrxn);
$this->db->where('voucher_person_account_id',$userId);
if ($this->db->trans_status() === false){
$this->db->trans_rollback();
return false;
}else{
$this->db->trans_commit();
return true;
}
return $query_result;
return true;
}else{
return false;
}
}
I am giving where condition
$this->db->update('ts_voucher', $openingBalTrxn);
$this->db->where('voucher_person_account_id',$userId);
for update one record it updates all voucher_amount column record
you need to run first your .where before your .update. See documentation here
$this->db->where('voucher_person_account_id',$userId);
$this->db->update('ts_voucher', $openingBalTrxn);
Your update query false. where clause first and other condition where first than update function call just copy this function and fix your problem.
public function updateConsignor($myData){
extract($myData);
$this->db->set('user_full_name' , $user_full_name);
$this->db->set('user_opening_balance' , $user_opening_balance);
$this->db->where('user_id', $user_id);
if($this->db->update('ts_users')){
$userId = $myData['user_id'];
$this->db->trans_begin();
$openingBalTrxn = array(
'voucher_amount' => $myData['user_opening_balance'],
);
$this->db->where('voucher_person_account_id',$userId);
$this->db->update('ts_voucher', $openingBalTrxn);
if ($this->db->trans_status() === false){
$this->db->trans_rollback();
return false;
}else{
$this->db->trans_commit();
return true;
}
return $query_result;
return true;
}else{
return false;
}
Your update operation is working before the 'where' condition has a chance to work. That's why it's updating all records. Simply put the where condition first, then update.
I am trying to test transaction management in codeigniter. Below method is a function in a model class. If update_user_company_id method returns false, wrapper method save_user_and_company also returns. In this case, because the method returns before it reaches to
$this->db->trans_complete();
call, changes made by save_company and delete_company_requests methods are rolled back. This is what I want.
But what I want to learn is that instead of calling
$this->db->rollback();
I directly return from method.
Is this approach safe?
Is there a possibility that I may encounter a lock or some other problem in the future?
function save_user_and_company($user, $company_request) {
$result[STATU] = ERROR;
$this->db->trans_start();
$company = $this->companies_dao->save_company($company_request->company_name, $user->id);
if (!$company) {
$result[MESSAGE] = COMPANY_SAVE_ERROR;
return $result;
}
$company_request_result = $this->company_requests_model->delete_company_requests($company_request->id);
if (!$company_request_result) {
$result[MESSAGE] = COMPANY_REQUEST_DELETE_ERROR;
return $result;
}
$user_update = $this->users_dao->update_user_company_id($user->id, $company->id);
if (!$user_update) {
$result[MESSAGE] = USER_UPDATE_ERROR;
return $result;
}
$this->db->trans_complete();
$result[STATU] = SUCCESS;
$result[MESSAGE] = SUCCESSFUL;
return $result;
}
Thanks in advance!
Did you try like this....
Following code returns TRUE if transaction completes successfully.Otherwise it rollback your transaction and returns FALSE.Hope it will help you a lot..
function save_user_and_company($user, $company_request) {
$this->db->trans_begin(); //Begins your transaction
//Performs the transaction operations
$company = $this->companies_dao->save_company($company_request->company_name, $user->id);
$company_request_result = $this->company_requests_model->delete_company_requests($company_request->id);
$user_update = $this->users_dao->update_user_company_id($user->id, $company->id);
//Check whether transaction fails
if ($this->db->trans_status() === FALSE)
{
$this->db->trans_rollback();
$status = FALSE;
}
else
{
$this->db->trans_commit();
$status = TRUE;
}
return $status;
}
Good Evening,
I got a problem with the last insert id function with active record codeigniter, it works fine in mysql. But when i try it on SQL Server, the result always return false. Please kindly take a look on my code:
function transactions_start($data) {
$this->db->insert($this->table, $data);
$id = $this->db->insert_id();
$q = $this->db->affected_rows();
if ($q > 0) {
return $id;
} else {
return FALSE;
}
}
this is the result of $this->db->last_query()
select ##IDENTITY as id
the var_dump() result always returning bool(false).
I'm developing this apps using MySQL and SQL Server, so i need to keep using the active record from codeigniter.
Any help would be great, thanks in advance!
The insert_id() function returns the id of last inserted row so you just check whether it is greater than 0 or not. Use it like
function transactions_start($data) {
$this->db->insert($this->table, $data);
$id = $this->db->insert_id();
if ($id > 0) {
return $id;
} else {
return FALSE;
}
}
Reference : https://ellislab.com/codeigniter/user-guide/database/helpers.html
I'm using apache, php, mysql and code igniter and I have a database set up. In the database I have two columns that both need to be unique in combo: latitude and longitude.
So I set up the database using this call:
alter table pano_raw add unique index(lat, lng)
Now when I insert values into the two columns (lat and lng) if the value is the same, the database should reject the write correct?
function addNewSet($data)
{
$this->db->insert('sets', $data);
}
This function should return a true or false, depending on the success of the read or write correct?
So now how so I alter it so that when it will return the row_id of the inserted record or return FALSE? If the write worked, I need the row_id, if it didn't I need FALSE so I can alter the code that called this function.
Would this work? I don't think so. Ideas?
function addNewSet($data)
{
$this->db->insert('sets', $data);
return $this->db->insert_id();
}
By default it wont return false, it will have a database error before returning false.
If you really want this, you need to go to application/config/database.php and change set this to false $db['default']['db_debug'] = FALSE;
Then you should be able to do this (assuming your table has an id field set to auto increment)
function addNewSet($data) {
if ($this->db->insert('sets', $data)) {
return $this->db->insert_id();
} else {
return FALSE;
}
}
Try this:
function addNewSet($data)
{
$result = $this->db->insert('sets', $data);
if ( $result )
return $this->db->insert_id();
return false;
}
You can use $this->db->affected_rows(); after inserting the data to check if any record was added (or affected).
So
function addNewSet($data)
{
$this->db->insert('sets', $data);
if($this->db->affected_rows()==1)
{
return $this->db->insert_id();
}
else
{
return false; // nothing was added!
}
}
Should do it (untested).