2017-12-22 55 views
1

1 개의 스케줄러에 2 개의 쿼리가 있습니다.SCHEDULE 문과 함께 트랜잭션을 사용하려면 어떻게해야합니까?

샘플 :

내가 MYSQL이 스케줄러와 트랜잭션을 사용할
CREATE EVENT worker 
ON SCHEDULE EVERY 1 DAY STARTS '2017-12-22 00:00:00' 
DO 

INSERT INTO tbl1 (column) values ('foo') 
UPDATE tbl2 SET column = 'foo' 

.

예를 들어, 업데이트 쿼리의 오류가 발생하면 삽입 쿼리를 롤백해야합니다. 어떻게해야합니까?

반응을위한 Thx.

+0

'START TRANSACTION;과'COMMIT;'를 사용하십시오. 여기에 'ROLLBACK'을 사용할 필요가 없습니다. –

+0

@PaulSpiegel 대답으로 내 의견을 쓰고, 내 친구, 그리고 어쩌면 그 진술은 스크립트에 가서 표시 –

답변

1

진술 내용을 START TRANSACTION;COMMIT; 사이에 넣으십시오. 트랜잭션 내의 명령문 중 하나라도 오류와 함께 실패하면 COMMIT 명령이 실행되지 않습니다. 따라서 변경 사항은 지속되지 않으며 명시 적으로 롤백 할 필요가 없습니다.

다음과 같은 스크립트를 테스트 할 수

DROP TABLE IF EXISTS `tbl1`; 
CREATE TABLE IF NOT EXISTS `tbl1` (
    `column` varchar(50) COLLATE utf8_unicode_ci NOT NULL, 
    `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP 
) ENGINE=InnoDB; 

DROP TABLE IF EXISTS `tbl2`; 
CREATE TABLE IF NOT EXISTS `tbl2` (
    `column` VARCHAR(50) NOT NULL COLLATE 'utf8_unicode_ci', 
    `ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    UNIQUE INDEX `column` (`column`) 
) ENGINE=InnoDB; 

DROP TABLE IF EXISTS `worker_log`; 
CREATE TABLE `worker_log` (
    `ts` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP 
) ENGINE=InnoDB; 

DROP EVENT IF EXISTS `worker`; 
DELIMITER // 
CREATE DEFINER=`root`@`localhost` EVENT `worker` ON SCHEDULE EVERY 10 SECOND 
STARTS NOW() + INTERVAL 10 SECOND 
ENDS NOW() + INTERVAL 70 SECOND 
ON COMPLETION PRESERVE ENABLE DO BEGIN 
    INSERT INTO worker_log (`ts`) values (NOW()); 
    START TRANSACTION; 
     INSERT INTO tbl1 (`column`) values ('foo'); 
     INSERT INTO tbl2 (`column`) values ('foo'); 
    COMMIT; 
END// 
DELIMITER ; 

SET GLOBAL event_scheduler = ON; 

지금 잠깐 당신의 테이블에 기록 된 내용을 보면 :

select * from worker_log; 

ts 
------------------- 
2017-12-23 16:24:44 
2017-12-23 16:24:54 
2017-12-23 16:25:04 
2017-12-23 16:25:14 
2017-12-23 16:25:24 
2017-12-23 16:25:34 
2017-12-23 16:25:44 

당신은 이벤트가 모든 실행 된 것을 볼 수 10 초 (정의 된대로).

select * from tbl1; 

column | ts 
-------+----------------------- 
foo | 2017-12-23 16:24:44 

select * from tbl2; 

column | ts 
-------+-------------------- 
foo | 2017-12-23 16:24:44 

그러나 여기서 트랜잭션 내의 명령문은 처음 실행시에만 영향을 미침을 알 수 있습니다. 이는 tbl2에있는 columnUNIQUE으로 정의되고 첫 번째 실행 후 두 번째 명령문이이 열에 동일한 값을 삽입하려고했기 때문에 실패했기 때문입니다. 그러나 첫 번째 문은 아무 문제없이 실행해야하지만 (tbl1.columnUNIQUE이 아니기 때문에) 계속 유지되지 않습니다.