코드 점화기 트랜잭션
코드 점화기 트랜잭션을 사용하고 있습니다.
$this->db->trans_start();
$this->db->query('AN SQL QUERY...');
$this->db->trans_complete();
이것은 잘 작동합니다. 문제는 내부의 문제입니다.trans_start그리고.trans_complete다른 기능들을 호출하고 있는데 그 기능들은 데이터베이스를 다루고 있어서 삽입과 업데이트가 포함되어 있고 일부 삭제도 있습니다.ex:
$this->db->trans_start();
$this->utils->insert_function($data);
$this->utils->update_function2($test);
$this->db->trans_complete();
이제 이러한 기능이 실행되고 오류가 발생하면 CodeIgniter는 롤백을 수행하지 않습니다.
그런 문제를 해결하는 가장 좋은 방법은 무엇입니까?
제가 생각하고 있는 유일한 해결책은 그 함수들과 그 함수 안에서 오류를 반환하는 것입니다.trans_stat그리고.trans_complete) 그리고 에러 테스트를 반환할 경우,$this->db->trans_rollback
ex:
$this->db->trans_start();
$result = $this->utils->insert_function($data);
if($result === false){
$this->db->trans_rollback();
}
$this->db->trans_complete();
더 좋은 방법이 없을까요?
업데이트 1:
요청하신 외부 기능 샘플로 전화 드립니다.
// 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);
}
으로.
transactions데이터를 안전하게 삽입할 수 있도록 데이터베이스를 지원하는 것을 의미합니다.그래서 Codeigniter에서는 Controller가 아닌 Model에 모든 데이터베이스 관련 기능을 씁니다.그리고 두 번째 코드(작동하지 않는 코드)에서 당신은 거기에 뾰족한 모델을 가지고 있습니다.utils너무 간단해서 안 될 거라고 확신합니다.모델과 컨트롤러가 병렬인 삽입 데이터가 아니기 때문입니다.거래는 모델에 코딩되어야 합니다(답변에 모델에 적겠습니다).
이 물건들도 같이 실어요.
- 데이터베이스 라이브러리
- 모델 클래스
- URL 도우미
- 세션
가정
당신이 사용한 코드에$data그리고.$test대배열로 데이터를 두 이 있다고 합니다.따라서 데이터를 삽입하고 업데이트하기 위한 두 개의 배열이 있다고 가정합니다.
데이터 세트
$data = array(
'title' => 'My title' ,
'name' => 'My Name' ,
'date' => 'My date'
);
$id = 007;
$test = array(
'title' => $title,
'name' => $name,
'date' => $date
);
유어 코드
$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;
}
메모들
- 기본적으로 코드 점화기는 모든 트랜잭션을 엄격 모드로 실행합니다.엄격 모드를 사용하도록 설정하면 트랜잭션 그룹을 여러 개 실행하는 경우 한 그룹에서 실패하면 모든 그룹이 롤백됩니다. 엄격 모드를 사용하지 않도록 설정하면 각 그룹이 독립적으로 처리되므로 한 그룹이 실패해도 다른 그룹에는 영향을 주지 않습니다.
제가 시도한 것은 속임수에 가까웠지만, 저에게는 효과가 있었습니다.
$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();
}
이 문제는 CodeIgniter가 객체를 다루는 방식과 관련이 있다고 생각합니다.
다음 위치에서 "Creating Libraries" 섹션의 CI 설명서로 이동하는 경우:
다음과 관련된 섹션을 살펴봅니다.
$CI =& get_instance();
$CI->load->helper('url');
$CI->load->library('session');
$CI->config->item('base_url');
주 컨트롤러에서 데이터베이스 클래스를 로드/인스턴스트하거나 자동 로드를 사용하여 클래스를 명시적으로 로드했습니다.
그런 다음 트랜잭션을 열고 유틸리티 라이브러리를 통해 데이터베이스 기능에 액세스합니다.
하지만 일단 사용하면$this-db라이브러리에서 트랜잭션과 관련된 복사본이 아니라 데이터베이스 인스턴스의 다른 복사본에 액세스하는 것입니다.
동일한 인스턴스에 액세스하려면 get_instance() 함수를 사용해야 합니다.
그것이 당신의 문제를 해결해 줄 것이라고 생각합니다.기능을 다양한 모듈로 분리하는 독창적인 코딩 스타일이 훌륭합니다.당신은 이 추가적인 세부사항을 이해하기만 하면 됩니다.
롤백이 예상대로 작동하는지 확인해 주시기 바랍니다.
코드의 내장은 다음과 같은 컨트롤러로 구성됩니다.
$this->db->trans_start();
$this->User_profile_m->create_new_user_profile();
$this->User_profile_m->create_new_user();
$this->db->trans_complete();
간단한 모델과user_profile_m데이터 지속성 처리:
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);
}
기본적으로 시연에서는 두 개의 삽입(두 개의 테이블에서 하나씩)을 시도합니다.한 삽입에 실패하면 다른 삽입은 롤백됩니다.
이것을 CodeIgniter 2.1.3에서 만들었고, GitHub을 통해 애플리케이션 파일을 이용할 수 있게 하거나 지퍼를 올려 당신에게 보낼 수 있습니다.
이 절차를 시도해 보십시오.정말 잘 어울려요 :)
$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();
}
참고: 반드시 사용하십시오.$this->db->trans_begin()수동 트랜잭션을 실행할 때는 그렇지 않습니다.$this->db->trans_start().
$this -> db -> trans_begin();
$this -> utils -> insert_function ( $data );
$this -> utils -> update_function2 ( $test );
$this -> db -> trans_complete ();
MySql을 사용하는 경우 인증, InnoDb 형식으로 사용
단일 삽입 또는 업데이트 레코드의 경우 effected_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());
}
언급URL : https://stackoverflow.com/questions/15224826/codeigniter-transactions
'programing' 카테고리의 다른 글
| Clean C 코드를 작성하는 동안 ARM 미정렬 메모리 액세스의 이점 활용 (0) | 2023.10.18 |
|---|---|
| Jquery AJAX로 페이지 프레임 로드 (0) | 2023.10.18 |
| 오라클의 스파크 쿼리(로드)가 SQOOP에 비해 매우 느린 이유는 무엇입니까? (0) | 2023.10.18 |
| 오라클 SQL 개발자의 사용자 스니펫을 쉽게 백업할 수 있는 방법이 있습니까? (0) | 2023.10.18 |
| 워드프레스:대량의 모든 게시물에서 "분류되지 않은" 범주를 제거하려면 어떻게 해야 합니까? (0) | 2023.10.18 |