복붙노트

PHP + MySQL 트랜잭션 예제

PHP

PHP + MySQL 트랜잭션 예제

나는 MySQL 트랜잭션이 사용되는 PHP 파일의 일반적인 예를 실제로 발견하지 못했다. 그 간단한 예를 보여줄 수 있습니까?

그리고 또 하나의 질문입니다. 나는 이미 많은 프로그래밍을했고 트랜잭션을 사용하지 않았다. header.php에 PHP 함수 또는 어떤 것을 넣을 수 있습니까? 하나의 mysql_query가 실패하면 다른 실패도 발생합니다.

나는 그것을 알아 냈다고 생각한다. 그렇지?

mysql_query("SET AUTOCOMMIT=0");
mysql_query("START TRANSACTION");

$a1 = mysql_query("INSERT INTO rarara (l_id) VALUES('1')");
$a2 = mysql_query("INSERT INTO rarara (l_id) VALUES('2')");

if ($a1 and $a2) {
    mysql_query("COMMIT");
} else {        
    mysql_query("ROLLBACK");
}

해결법

  1. ==============================

    1.

    트랜잭션으로 작업 할 때 일반적으로 사용하는 아이디어는 다음과 같이 보입니다 (준 의사 코드).

    try {
        // First of all, let's begin a transaction
        $db->beginTransaction();
    
        // A set of queries; if one fails, an exception should be thrown
        $db->query('first query');
        $db->query('second query');
        $db->query('third query');
    
        // If we arrive here, it means that no exception was thrown
        // i.e. no query has failed, and we can commit the transaction
        $db->commit();
    } catch (Exception $e) {
        // An exception has been thrown
        // We must rollback the transaction
        $db->rollback();
    }
    

    이 아이디어로 쿼리가 실패하면 Exception이 throw되어야합니다.

    불행히도 마법과 관련된 것은 없습니다. 어딘가에 지시를 내리고 트랜잭션을 자동으로 처리 할 수는 없습니다. 트랜잭션에서 실행해야하는 쿼리 그룹을 지정해야합니다.

    예를 들어, 트랜잭션 (시작 전)과 트랜잭션 후 (커밋 또는 롤백 후)에 다른 두 개의 쿼리를 사용하면 어떤 일이 발생했는지에 관계없이 쿼리를 실행하게됩니다. 그렇지 않은 경우).

  2. ==============================

    2.

    나는 그것을 알아 냈다고 생각한다. 그렇지?

    mysql_query("START TRANSACTION");
    
    $a1 = mysql_query("INSERT INTO rarara (l_id) VALUES('1')");
    $a2 = mysql_query("INSERT INTO rarara (l_id) VALUES('2')");
    
    if ($a1 and $a2) {
        mysql_query("COMMIT");
    } else {        
        mysql_query("ROLLBACK");
    }
    
  3. ==============================

    3.

    <?php
    
    // trans.php
    function begin(){
        mysql_query("BEGIN");
    }
    
    function commit(){
        mysql_query("COMMIT");
    }
    
    function rollback(){
        mysql_query("ROLLBACK");
    }
    
    mysql_connect("localhost","Dude1", "SuperSecret") or die(mysql_error());
    
    mysql_select_db("bedrock") or die(mysql_error());
    
    $query = "INSERT INTO employee (ssn,name,phone) values ('123-45-6789','Matt','1-800-555-1212')";
    
    begin(); // transaction begins
    
    $result = mysql_query($query);
    
    if(!$result){
        rollback(); // transaction rolls back
        echo "transaction rolled back";
        exit;
    }else{
        commit(); // transaction is committed
        echo "Database transaction was successful";
    }
    
    ?>
    
  4. ==============================

    4.

    이것이 "php mysql transaction"에 대한 Google의 첫 번째 결과이기 때문에, 원래 작성자가 원했던 것처럼 mysqli로이를 수행하는 방법을 명시 적으로 보여주는 답변을 추가한다고 생각했습니다. 다음은 PHP / mysqli를 사용한 트랜잭션의 간단한 예입니다.

    // let's pretend that a user wants to create a new "group". we will do so
    // while at the same time creating a "membership" for the group which
    // consists solely of the user themselves (at first). accordingly, the group
    // and membership records should be created together, or not at all.
    // this sounds like a job for: TRANSACTIONS! (*cue music*)
    
    $group_name = "The Thursday Thumpers";
    $member_name = "EleventyOne";
    $conn = new mysqli($db_host,$db_user,$db_passwd,$db_name); // error-check this
    
    // note: this is meant for InnoDB tables. won't work with MyISAM tables.
    
    try {
    
        $conn->autocommit(FALSE); // i.e., start transaction
    
        // assume that the TABLE groups has an auto_increment id field
        $query = "INSERT INTO groups (name) ";
        $query .= "VALUES ('$group_name')";
        $result = $conn->query($query);
        if ( !$result ) {
            $result->free();
            throw new Exception($conn->error);
        }
    
        $group_id = $conn->insert_id; // last auto_inc id from *this* connection
    
        $query = "INSERT INTO group_membership (group_id,name) ";
        $query .= "VALUES ('$group_id','$member_name')";
        $result = $conn->query($query);
        if ( !$result ) {
            $result->free();
            throw new Exception($conn->error);
        }
    
        // our SQL queries have been successful. commit them
        // and go back to non-transaction mode.
    
        $conn->commit();
        $conn->autocommit(TRUE); // i.e., end transaction
    }
    catch ( Exception $e ) {
    
        // before rolling back the transaction, you'd want
        // to make sure that the exception was db-related
        $conn->rollback(); 
        $conn->autocommit(TRUE); // i.e., end transaction   
    }
    

    또한 PHP 5.5에는 새로운 메소드 mysqli :: begin_transaction이 있습니다. 그러나 이것은 PHP 팀에 의해 아직 문서화되지 않았으며, PHP 5.3에 아직도 붙어 있습니다. 그래서 그것에 대해 언급 할 수 없습니다.

  5. ==============================

    5.

    사용중인 스토리지 엔진을 확인하십시오. 이것이 MyISAM 인 경우 MyISAM이 아닌 InnoDB 스토리지 엔진 만 트랜잭션을 지원하기 때문에 Transaction ( 'COMMIT', 'ROLLBACK')은 지원되지 않습니다.

  6. ==============================

    6.

    쿼리 벡터를 얻고 트랜잭션을 수행하는 함수를 만들었습니다. 아마 누군가가 유용하다는 것을 알게 될 것입니다.

    function transaction ($con, $Q){
            mysqli_query($con, "START TRANSACTION");
    
            for ($i = 0; $i < count ($Q); $i++){
                if (!mysqli_query ($con, $Q[$i])){
                    echo 'Error! Info: <' . mysqli_error ($con) . '> Query: <' . $Q[$i] . '>';
                    break;
                }   
            }
    
            if ($i == count ($Q)){
                mysqli_query($con, "COMMIT");
                return 1;
            }
            else {
                mysqli_query($con, "ROLLBACK");
                return 0;
            }
        }
    
  7. ==============================

    7.

    나는 이것이 있었지만 이것이 올바른지 확신 할 수 없었다. 이것을 시도해 볼 수도 있습니다.

    mysql_query("START TRANSACTION");
    $flag = true;
    $query = "INSERT INTO testing (myid) VALUES ('test')";
    
    $query2 = "INSERT INTO testing2 (myid2) VALUES ('test2')";
    
    $result = mysql_query($query) or trigger_error(mysql_error(), E_USER_ERROR);
    if (!$result) {
    $flag = false;
    }
    
    $result = mysql_query($query2) or trigger_error(mysql_error(), E_USER_ERROR);
    if (!$result) {
    $flag = false;
    }
    
    if ($flag) {
    mysql_query("COMMIT");
    } else {        
    mysql_query("ROLLBACK");
    }
    

    여기에서 아이디어 : http://www.phpknowhow.com/mysql/transactions/

  8. ==============================

    8.

    PDO 연결을 사용할 때 :

    $pdo = new PDO('mysql:host=localhost;dbname=mydb;charset=utf8', $user, $pass, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // this is important
    ]);
    

    종종 트랜잭션 관리를 위해 다음 코드를 사용합니다.

    function transaction(Closure $callback)
    {
        global $pdo; // let's assume our PDO connection is in a global var
    
        // start the transaction outside of the try block, because
        // you don't want to rollback a transaction that failed to start
        $pdo->beginTransaction(); 
        try
        {
            $callback();
            $pdo->commit(); 
        }
        catch (Exception $e) // it's better to replace this with Throwable on PHP 7+
        {
            $pdo->rollBack();
            throw $e; // we still have to complain about the exception
        }
    }
    

    사용 예 :

    transaction(function()
    {
        global $pdo;
    
        $pdo->query('first query');
        $pdo->query('second query');
        $pdo->query('third query');
    });
    

    이렇게하면 트랜잭션 관리 코드가 프로젝트 전체에 중복되지 않습니다. 이것은 좋은 일입니다. 왜냐하면이 스레드의 다른 PDO 관련 답변에서 볼 때, 실수를 저지르기 쉽습니다. 가장 일반적인 것들은 예외를 되돌려 놓고 try 블록 내에서 트랜잭션을 시작하는 것을 잊어 버리는 것입니다.

  9. ==============================

    9.

    mysqli_multi_query를 사용한 절차 적 스타일 예제는 $ query가 세미콜론으로 분리 된 문장으로 채워져 있다고 가정한다.

    mysqli_begin_transaction ($link);
    
    for (mysqli_multi_query ($link, $query);
        mysqli_more_results ($link);
        mysqli_next_result ($link) );
    
    ! mysqli_errno ($link) ?
        mysqli_commit ($link) : mysqli_rollback ($link);
    
  10. from https://stackoverflow.com/questions/2708237/php-mysql-transactions-examples by cc-by-sa and MIT lisence