Programing

PHP + MySQL 트랜잭션 예제

lottogame 2020. 3. 21. 10:11
반응형

PHP + MySQL 트랜잭션 예제


MySQL 트랜잭션이 사용되는 PHP 파일의 일반적인 예를 찾지 못했습니다. 간단한 예를 보여 주시겠습니까?

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


나는 그것을 이해했다고 생각한다, 맞습니까? :

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");
}

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

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();
}


이 아이디어로 쿼리가 실패하면 예외가 발생해야합니다.

  • 구성 방법에 따라 PDO가이를 수행 할 수 있습니다.
  • 그렇지 않으면 다른 API를 사용하여 쿼리를 실행하는 데 사용 된 함수의 결과를 테스트하고 예외를 직접 throw해야 할 수도 있습니다.


불행히도 관련된 마술은 없습니다. 어딘가에 지시를 내릴 수 없으며 트랜잭션을 자동으로 수행 할 수 있습니다. 트랜잭션에서 실행해야하는 쿼리 그룹을 구체적으로 지정해야합니다.

예를 들어, 매우 자주 거래하기 전에 쿼리의 몇 가지를해야 합니다 (이전 begin) 및 거래 후 쿼리의 또 다른 커플 (중 후 commit또는 rollback) 그 쿼리에 무슨 일이 있었는지에 상관없이 실행하고 당신이 원하는 것 (여부) 에 거래.


나는 그것을 이해했다고 생각한다, 맞습니까? :

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");
}

<?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";
}

?>

이것이 "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에 갇혀 있으므로 주석을 달 수 없습니다.


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


쿼리 벡터를 얻고 트랜잭션을 수행하는 함수를 만들었습니다. 어쩌면 누군가 유용하다고 생각할 것입니다.

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;
        }
    }

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블록 내에서 트랜잭션을 시작하는 것 입니다.


나는 이것을 가지고 있었지만 이것이 정확한지 확신하지 못한다. 이것도 시도해 볼 수 있습니다.

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/


을 사용한 절차 적 스타일 예제 중 하나 는 세미콜론으로 구분 된 명령문으로 채워져 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);

참고 URL : https://stackoverflow.com/questions/2708237/php-mysql-transactions-examples

반응형