Operacje Codeigniter


Korzystam z transakcji Codeigniter
$this->db->trans_start();
$this->db->query('AN SQL QUERY...');
$this->db->trans_complete();

To działa świetnie, problem polega na tym, że wewnątrz
trans_start
i
trans_complete
wywołuję inne funkcje, które zajmują się bazą danych, więc zawierają wstawki i aktualizacje, a niektóre usuń ... np .:
$this->db->trans_start();
$this->utils->insert_function($data);
$this->utils->update_function2($test);
$this->db->trans_complete();

Teraz, jeśli te funkcje są uruchomione i wystąpią błędy, CodeIgniter nie wycofa się.
Jak najlepiej poradzić sobie z takim problemem?
Jedynym rozwiązaniem, które mam na myśli, jest zwrócenie błędu z tych funkcji i wewnątrz tych funkcji dodawania (
trans_stat
i
trans_complete
) i jeśli zwróci błąd test, do
$ this- & > db- & > trans_rollback
były:
$this->db->trans_start();
$result = $this->utils->insert_function($data);
if($result === false){
$this->db->trans_rollback();
}
$this->db->trans_complete();

Czy jest lepszy sposób, aby to zrobić?

Zaktualizuj 1

:
Zgodnie z żądaniem przykładowa funkcja zewnętrzna, którą wywołuję:
// insert_function contains $rec = array( 'numero' => $numero,
'transaction_id' => $id,
'debit' => $product_taxes['amount_without_taxes'],
'date' => $data['date_transaction'],
);
$this->addExerciceAccountingRecords($rec); and addExerciceAccountingRecords contains function addExerciceAccountingRecords($records) {
$this->db->insert('transactions_exercices', $records);
}

Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Korzystanie z
transakcji
oznacza obsługę bazy danych w celu bezpiecznego wprowadzania danych. Dlatego w Codeigniter piszemy wszystko

funkcje związane z bazą danych w

Model

zamiast w kontrolerze.
... W drugim kodzie (który nie działa) określiłeś tam model. (
utils
). tak proste, jestem pewien, że to nie zadziała. Ponieważ nie jest to wstawianie danych z modelem równoległym i kontrolerem. Transakcja musi być zakodowana w modelu (

napiszę w modelu w mojej odpowiedzi

).

Pobierz również te materiały

  • Biblioteka baz danych
  • Klasa modelu
  • Pomocnik adresu URL
  • Sesja


Założenia

W swoim kodzie użyłeś
$ data
i
$ test
jako tablicy. Zakładam więc, że istnieją dwie tablice do wstawiania i aktualizowania danych.

Twoje zbiory danych

$data = array( 'title' => 'My title' ,
'name' => 'My Name' ,
'date' => 'My date');$id = 007;
$test = array( 'title' => $title,
'name' => $name,
'date' => $date);


Twój kod

$this->db->trans_start(); # Starting Transaction
$this->db->trans_strict(FALSE); # See Note 01. If you wish can remove as well $this->db->insert('table_name', $data); # Inserting data# Updating data
$this->db->where('id', $id);
$this->db->update('table_name', $test); $this->db->trans_complete(); # Completing transaction/*Optional*/if ($this->db->trans_status() === FALSE) {
# Something went wrong.
$this->db->trans_rollback();
return FALSE;
}
else {
# Everything is Perfect.
# Committing data to the database.
$this->db->trans_commit();
return TRUE;
}


Nagrania

  • Domyślnie Codeigniter uruchamia wszystkie transakcje w trybie ścisłym. Gdy w zestawie tryb ścisły, jeśli uruchomisz wiele grup transakcji, a jeśli jedna z nich zawiedzie, wszystkie grupy zostaną wycofane. Jeśli ścisły reżim niepełnosprawny , każda grupa obrobiony cokolwiek , tj. awaria jednej grupy nie będzie miała wpływu ktoś jeszcze .
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

To, co próbowałem, było bardziej sztuczką, ale udało mi się.
$this->db->trans_begin();
$rst1= $this->utils->insert_function($data);
$rst2 = $this->utils->update_function2($test);
if($this->db->trans_status() === FALSE || !isset($rst1) || !isset($rst2)){
$this->db->trans_rollback();
}else{
$this->db->trans_commit();
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Podejrzewam, że problem dotyczy sposobu, w jaki CodeIgniter obsługuje obiekty.
Jeśli przejdziesz do dokumentacji CI w sekcji „Tworzenie bibliotek” pod adresem:
http://ellislab.com/codeignite ... .html

http://ellislab.com/codeignite ... .html
i spójrz na sekcję związaną z:
$CI =& get_instance();
$CI->load->helper('url');
$CI->load->library('session');
$CI->config->item('base_url');

W głównym kontrolerze załadowałeś/utworzyłeś klasę bazy danych albo przez automatyczne ładowanie, albo przez jawne ładowanie klasy.
Następnie otwierasz transakcję, a następnie uzyskujesz dostęp
funkcje bazy danych poprzez bibliotekę narzędzi.
Jednak gdy użyjesz
$ this-db
w swojej bibliotece, w rzeczywistości masz dostęp do innej kopii instancji bazy danych, a NIE tej powiązanej z Twoją transakcją.
Aby uzyskać dostęp do tej samej instancji, musisz użyć funkcji get_instance ().
Myślę, że to powinno rozwiązać twój problem. Twój oryginalny styl kodowania do oddzielania funkcji
dla różnych modułów jest doskonały. Musisz tylko zrozumieć ten dodatkowy szczegół.
Spróbuj i upewnij się, że przywracanie działa zgodnie z oczekiwaniami.
Elementy wewnętrzne kodu składają się z następującego kontrolera:
$this->db->trans_start();
$this->User_profile_m->create_new_user_profile();
$this->User_profile_m->create_new_user();
$this->db->trans_complete();

i prosty model
user_profile_m
do pracy z trwałością:
function create_new_user()
{
$data['user_name_usr'] = $this->input->post('user_name');
$data['create_date_usr'] = NULL; $this->db->insert('user_usr', $data);
}function create_new_user_profile()
{
$data['user_name_pro'] = $this->input->post('user_name');
$data['user_description_pro'] = $this->input->post('user_description');
$data['create_date_pro'] = NULL; $this->db->insert('user_profile_pro', $data);
}

Zasadniczo demo próbuje zrobić dwie wstawki (po jednej w każdej z dwóch tabel).
Jeśli jedna wkładka zawiedzie, druga wycofuje się.
Zbudowałem to w CodeIgniter 2.1.3 i mogę udostępnić pliki aplikacji przez GitHub lub zip i wysłać je do Ciebie.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Uwaga: pamiętaj, aby używać
$ this- & > db- & > trans_begin ()
podczas wykonywania transakcji ręcznych, a NIE
$ this- & > db- & > trans_start ()
.

$this -> db -> trans_begin(); 
$this -> utils -> insert_function ( $data );
$this -> utils -> update_function2 ( $test );
$this -> db -> trans_complete ();

Zaświadczenie w przypadku korzystania z MySql, użyj w formacie InnoDb
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Spróbuj tej procedury. To faktycznie działa dla mnie :)
$this->db->trans_start();
$this->utils->insert_function($data);
$this->utils->update_function2($test);
if($this->db->trans_status() === FALSE){
$this->db->trans_rollback();
}else{
$this->db->trans_complete();
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

W przypadku pojedynczego wstawienia lub aktualizacji rekordu można użyć funkcji impact_rows
$this->db->insert('table_name', xss_clean($data));
//Check if there is a record affected
if($this->db->affected_rows() > 0)
{
return true;
}
else
{
// if not succeeded
// check your last query
die($this->db->last_query());
}

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się