programing

코드 점화기 트랜잭션

mailnote 2023. 10. 18. 22:58
반응형

코드 점화기 트랜잭션

코드 점화기 트랜잭션을 사용하고 있습니다.

$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너무 간단해서 안 될 거라고 확신합니다.모델과 컨트롤러가 병렬인 삽입 데이터가 아니기 때문입니다.거래는 모델에 코딩되어야 합니다(답변에 모델에 적겠습니다).


이 물건들도 같이 실어요.

  1. 데이터베이스 라이브러리
  2. 모델 클래스
  3. URL 도우미
  4. 세션

가정

당신이 사용한 코드에$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;
}

메모들

  1. 기본적으로 코드 점화기는 모든 트랜잭션을 엄격 모드로 실행합니다.엄격 모드사용하도록 설정하면 트랜잭션 그룹을 여러실행하는 경우 그룹에서 실패하면 모든 그룹이 롤백됩니다. 엄격 모드사용하지 않도록 설정하면 각 그룹이 독립적으로 처리되므로 한 그룹이 실패해도 다른 그룹에는 영향을 주지 않습니다.

제가 시도한 것은 속임수에 가까웠지만, 저에게는 효과가 있었습니다.

$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

반응형