programing

트랜잭션 내 Mysql 트랜잭션

randomtip 2022. 10. 22. 09:42
반응형

트랜잭션 내 Mysql 트랜잭션

mysql 데이터베이스로 동작하는 PHP 스크립트에서 최근 다른 트랜잭션 안에 있는 트랜잭션을 사용할 필요가 있었습니다.모든 테스트에서 정상적으로 동작하고 있는 것 같습니다만, 이 사용법에 관한 문서를 찾을 수 없습니다.

확실히 하고 싶습니다만, 거래내에서의 거래는 mysql에서 유효합니까?그렇다면 중첩된 트랜잭션의 깊이를 알 수 있는 방법이 있습니까? (즉, 정상으로 되돌리려면 몇 개의 롤백이 필요합니까?)

미리 감사드려요, 브라이언

다른 사람들의 대답과는 달리, 거래 내에서 효과적으로 거래를 만들 수 있고 매우 쉽습니다.SAVEPOINT 로케이션을 작성하고 ROLLBLL TO 세이브포인트를 사용하여 트랜잭션의 일부를 롤백합니다.여기서 세이브포인트는 세이브포인트에 붙이는 임의의 이름입니다.MySQL 문서 링크: http://dev.mysql.com/doc/refman/5.0/en/savepoint.html 트랜잭션 내 모든 쿼리는 암묵적으로 커밋되는 타입이 되어서는 안 됩니다.그렇지 않으면 트랜잭션 전체가 커밋됩니다.

예:

START TRANSACTION;

# queries that don't implicitly commit

SAVEPOINT savepoint1;

# queries that don't implicitly commit

# now you can either ROLLBACK TO savepoint1, or just ROLLBACK to reverse the entire transaction.

SAVEPOINT savepoint2;

# queries that don't implicitly commit

# now you can ROLLBACK TO savepoint1 OR savepoint2, or ROLLBACK all the way.
# e.g.

ROLLBACK TO savepoint1;
COMMIT; # results in committing only the part of the transaction up to savepoint1

PHP에서는 다음과 같은 코드를 작성했습니다.완벽하게 동작합니다.

foreach($some_data as $key => $sub_array) {
  $result = mysql_query('START TRANSACTION'); // note mysql_query is deprecated in favor of PDO
  $rollback_all = false; // set to true to undo whole transaction
  for($i=0;$i<sizeof($sub_array);$i++) {
    if($sub_array['set_save'] === true) {
      $savepoint = 'savepoint' . $i;
      $result = mysql_query("SAVEPOINT $savepoint");
    }
    $sql = 'UPDATE `my_table` SET `x` = `y` WHERE `z` < `n`'; // some query/queries
    $result = mysql_query($sql); // run the update query/queries

    $more_sql = 'SELECT `x` FROM `my_table`'; // get data for checking
    $result = mysql_query($more_sql);
    
    $rollback_to_save = false; // set to true to undo to last savepoint
    while($row = mysql_fetch_array($result)) {
      // run some checks on the data
      if( /*some check says to go back to savepoint */) {
        $rollback_to_save = true; // or just do the rollback here.
      }
      if( /* some check says to rollback entire transaction */ ) {
        $rollback_all = true;
      }
    }
    if($rollback_all === true) {
      mysql_query('ROLLBACK'); // rollback entire transaction
      break; // break out of for loop, into next foreach
    }
    if($rollback_to_save = true) {
      mysql_query("ROLLBACK TO $savepoint"); // undo just this part of for loop
    }
  } // end of for loop
  mysql_query('COMMIT'); // if you don't do this, the whole transaction will rollback
}

매뉴얼의 12.3.3 페이지에 관심이 있을 수 있습니다. 암묵적인 커밋의 원인이 되는 스테이트먼트: 몇 개의 문장을 인용합니다.

항에 되어 있는 및 그)는 으로 종료합니다. 마치, 「 「」 「 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」 「」를 실행한 것과 .COMMIT를 참조해 주세요.

그리고 페이지의 조금 더 먼 부분:

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ BEGIN,LOCK TABLES,SET autocommit = 1), ('1'),START TRANSACTION,UNLOCK TABLES.

다음 단락도 참조하십시오.

트랜잭션은 중첩할 수 없습니다.
은 암묵적인 입니다.commit됨(「」을 때)START TRANSACTION★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★♪

확실히 하고 싶습니다만, 거래내에서의 거래는 mysql에서 유효합니까?

아니요.

MySql my my my my my 。하지만 그것을 모방할 수 있는 몇 가지 방법이 있습니다.우선, 트랜잭션의 형태로 save point를 사용할 수 있기 때문에, 2개의 레벨의 트랜잭션을 얻을 수 있습니다.테스트에 사용한 적이 있습니다만, 프로덕션 코드에서 사용하는 경우는 제한에 대해서는 잘 모르겠습니다.은 두 입니다.begin transaction카운터를 늘립니다.각각에 대해서commit, 감소합니다.일단 0이 되면, 당신은 실제를 합니다.commit여기에는 분명한 제한이 있습니다. 예를 들어 롤백하면 모든 트랜잭션이 롤백되지만 트랜잭션을 오류 처리에만 사용하는 경우에는 허용될 수 있습니다.

이 스레드에는 몇 가지 훌륭한 답이 있습니다.그러나 MySQL 스토리지 엔진으로 innoDB를 사용하고 MySQL 5.0.3 이상을 사용하는 경우, 별도의 작업이나 이 스레드 내의 다른 사용자가 설명하는 고급 기술 없이 바로 네스트된 트랜잭션을 얻을 수 있습니다.

XA 트랜잭션에 관한 MySQL 문서:

MySQL 5.0.3 이상에서는 XA 트랜잭션을 서버 측에서 지원합니다.현재 이 지원은 InnoDB 스토리지 엔진에서 사용할 수 있습니다.MySQL XA 구현은 X/Open CAE 문서 분산 트랜잭션 처리에 기반합니다.XA 사양.이 문서는 The Open Group에 의해 발행되며 http://www.opengroup.org/public/pubs/catalog/c193.htm에서 구할 수 있습니다.현재의 XA 실장의 제한은 섹션 E.5의 "XA 트랜잭션의 제한"에 설명되어 있습니다.

고객만을 위한 XA 트랜잭션 예시:

# Start a new XA transaction
XA START;

    # update my bank account balance, they will never know!
    UPDATE `bank_accounts` SET `balance` = 100000 WHERE `id` = 'mine';

    # $100,000.00 is a bit low, I'm going to consider adding more, but I'm not sure so 
    # I will start a NESTED transaction and debate it...
    XA START;

        # max int money! woo hoo!
        UPDATE `bank_accounts` SET `balance` = 2147483647 WHERE `id` = 'mine';

    # maybe thats too conspicuous, better roll back
    XA ROLLBACK;


# The $100,000 UPDATE still applies here, but the max int money does not, going for it!
XA COMMIT;

# Oh No!  Sirens!  It's the popo's!!! run!!
# What the hell are they using ints for money columns anyway!  Ahhhh!

XA 트랜잭션용 MySQL 문서:

I <3 XA 거래 4 Eva!

메타드론 검사를 받아보는 게 좋을 거야MaxDB를 제외하고 MySQL은 중첩된 트랜잭션과 같은 어떤 것도 원격으로 지원하지 않습니다.

지원 내용 : http://dev.mysql.com/doc/refman/5.0/en/xa.html

언급URL : https://stackoverflow.com/questions/1490846/mysql-transactions-within-transactions

반응형