2013-07-01 2 views
0

프로젝트에서 많은 테이블의 행을 많이 삭제하고 업데이트하므로 트랜잭션을 사용하기로 결정했습니다. 그러나 트랜잭션은 오류가 발생하여 스크립트가 종료 될 때까지 커밋됩니다.오류가 발생하더라도 MySQL 트랜잭션이 커밋됩니다.

나는 그것 때문에 지원되지 않습니다 해당 서버에만 mysql_로하지 mysqli_ 또는 PDO를 사용합니다.

mysql_query("START TRANSACTION"); 
$res = mysql_query("some insert..."); 
if($res === false){ 
    //this save error log and exit script with die() or exit() 
    trigger_error(mysql_errno()."\n".mysql_error()); 
} 
$res = mysql_query("some delete..."); 
if($res === false){ 
    trigger_error(mysql_errno()."\n".mysql_error()); 
} 
mysql_query("COMMIT"); 

내 프로젝트에서 나는이 클래스를 mysql에 입력하면 안되지만이 방법으로 작동한다.

첫 번째 쿼리 오류가 발생한 후에 오류 로그가 저장되고 종료 스크립트가 종료됩니다. 그러나 삽입 된 데이터는 DB에 남아 있습니다. 하지만 COMMIT이 실행되지 않고 연결이 닫히면 자동으로 ROLLBACK이 발생합니다.

P. mysqli를 사용하는 것이 더 좋다는 것을 알고 있지만, mysql_mysqli_에 대해서도 동일합니다. 그렇지 않습니까?

+0

성공한 후에 만 ​​커밋하고 오류 후 롤백 – StasGrin

+0

성공한 후에 만 ​​커밋하지만 오류가 발생하면 롤백하지 않습니다. 나는 그것이 자동으로 생각. – Arxeiss

답변

1

http://dev.mysql.com/doc/refman/5.0/en/commit.htmlSET autocommit = 0입니다. 나는 당신이 그것을 자동 응답하지 않기를 원한다면 당신은 그것을 말할 필요가 있고, 그때 만 COMMITROLLBACK 당신의 진술을 부르지 않을 것이라고 믿는다.

그렇지 않으면 당신은 제대로 처리되지 수도 당신과 거래에 관련된 MySQL의에 대한 미래의 변화에 ​​대한 모든 작업을 할 MySQL의 신뢰의 위험에 ROLLBACK에 호출을하는 핸들러 코드를 가지고 있지만 그것은 최고 귀하의 코드에 의해.

+0

그건 그렇고, 당신이 올린 사이트에 'START TRANSACTION' 자동 커밋을 사용하지 못하게했습니다. 내 오류 기능에 롤백을 추가했습니다. 그러나 COMMIT가 실행되지 않고 'START TRANSACTION'이 자동 커밋을 비활성화하면 왜 데이터가 저장되었는지 이해하지 못합니다. – Arxeiss

+0

몰래, 미안, "진짜 디버그" – nrathaus

0

커밋 쿼리를 실행하지 않고 데이터가 데이터베이스에 있거나 커밋 된 것은 확실합니까?

MySQL documentation :

는, 문 하나의 시리즈 암시 적으로 자동 커밋 모드를 해제 START TRANSACTION 문 사용하려면 :

START 거래를;

SELECT @A : = SUM (급여) FROM table1 WHERE type = 1;

UPDATE table2 SET 요약 = @A WHERE type = 1;

COMMIT;

START TRANSACTION을 사용하면 COMMIT 또는 ROLLBACK으로 트랜잭션을 종료 할 때까지 자동 커밋이 비활성화 된 상태로 유지됩니다. 자동 확약 모드는 이전 상태로 되돌아갑니다.

sql> create table t10 (id integer auto_increment primary key, status char(32)) 

<?php 

    if(($link = mysql_connect("localhost", "db_user", "*****")) === false) 
    exit(1); 

    mysql_select_db("test", $link); 

    var_dump(mysql_query("start transaction;")); 
    var_dump(mysql_query("insert into t10 (status) values (\"foo1\"), (\"foo2\");")); 
    exit(); 
    //var_dump(mysql_query("commit;")); 
    var_dump(mysql_close()); 
?> 

값 foo1은과에서는 foo2는 데이터베이스 테이블 (T10)에 삽입되지 않습니다

나는 MySQL을 5.5과 PHP 5.3를 사용하여이 코드를 테스트했다. 또한 MySQL 트랜잭션은 "모두 또는 아무것도"규칙의 의미에서 완전히 원자 적이지 않다는 것을 명심하십시오.완료된 명령문의 절반으로 트랜잭션을 커밋 할 수 있고 나머지 절반은 실패했습니다 (소스 : Kouber Saparev, 2010 년 12 월 3 일 오전 11:01, MySQL 페이지 http://dev.mysql.com/doc/refman/5.5/en/ansi-diff-transactions.html).

테스트 케이스 : 우리는 실패 삽입 쿼리도 트랜잭션이 성공적으로 커밋 된 포함되지 않은 것을 볼

mysql> create table t7 (id integer primary key auto_increment, name text, lastname text); 
Query OK, 0 rows affected (0.04 sec) 

mysql> start transaction; 
Query OK, 0 rows affected (0.00 sec) 

mysql> insert into t7 (name, lastname) values('name1', 'lastname1'); 
Query OK, 1 row affected (0.00 sec) 

mysql> insert into t7 (name, lastname) values('name1', 'lastname1'); 
Query OK, 1 row affected (0.00 sec) 

mysql> insert into t7 (name, lastname) ('name1', 'lastname1'); 
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that 
corresponds to your MySQL server version for the right syntax to use near ''name 
1', 'lastname1')' at line 1 
mysql> commit; 
Query OK, 0 rows affected (0.01 sec) 

mysql> select * from t7; 
+----+-------+-----------+ 
| id | name | lastname | 
+----+-------+-----------+ 
| 1 | name1 | lastname1 | 
| 2 | name1 | lastname1 | 
+----+-------+-----------+ 
2 rows in set (0.00 sec) 

.

관련 문제