发布时间:2024-04-06 20:30:01
在数据库中,我们将一条 SQL 语句称为一次基本的操作。将若干条 SQL 语句“打包”在一起,共同执行一个完整的任务,这就是事务。BEGIN;
或者START TRANSACTION;
该命令用来标记一个事务的起始点。COMMIT;
提交事务意味着真正执行事务包含的 SQL 语句,并把对数据库的修改写入到磁盘上的物理数据库中。COMMIT 意味着事务结束,并且执行成功。+----+----------+-----+-----------+----------+ | ID | NAME | AGE | ADDRESS | SALARY | +----+----------+-----+-----------+----------+ | 1 | Ramesh | 32 | Ahmedabad | 2000.00 | | 2 | Khilan | 25 | Delhi | 1500.00 | | 3 | kaushik | 23 | Kota | 2000.00 | +----+----------+-----+-----------+----------+
mysql> BEGIN; mysql> INSERT INTO CUSTOMERS (NAME, AGE, ADDRESS, SALARY) VALUES ('Chaitali', 25, 'Mumbai', 6500.00 ); mysql> INSERT INTO CUSTOMERS (NAME, AGE, ADDRESS, SALARY) VALUES ('Hardik', 27, 'Bhopal', 8500.00 );
mysql> SELECT * FROM CUSTOMERS; +----+---------+-----+-----------+--------+ | id | name | age | address | salary | +----+---------+-----+-----------+--------+ | 1 | Ramesh | 32 | Ahmedabad | 2000 | | 2 | Khilan | 25 | Delhi | 1500 | | 3 | Kaushik | 23 | Kota | 2000 | +----+---------+-----+-----------+--------+您看,A 窗口对表的修改并没有影响到 B 窗口,B 窗口只能查看到修改之前的内容,这说明 A 窗口的修改动作并没有立即更新到物理数据库,所以在其它会话窗口中无法看到。
mysql> COMMIT;
mysql> SELECT * FROM CUSTOMERS; +----+----------+-----+-----------+--------+ | id | name | age | address | salary | +----+----------+-----+-----------+--------+ | 1 | Ramesh | 32 | Ahmedabad | 2000 | | 2 | Khilan | 25 | Delhi | 1500 | | 3 | Kaushik | 23 | Kota | 2000 | | 4 | Chaitali | 25 | Mumbai | 6500 | | 5 | Hardik | 27 | Bhopal | 8500 | +----+----------+-----+-----------+--------+您看,在 A 窗口提交事务以后,对表所做的修改才真正更新到物理数据库中,所以才能在其它会话窗口中查看到 A 窗口中插入的数据。
ROLLBACK;事务执行过程中如果发生了某种故障,事务不能继续执行,就可以撤销事务,此时对数据库的修改并不会保存到物理数据库中。撤销意味着事务结束,并且执行失败。
+----+----------+-----+-----------+--------+ | id | name | age | address | salary | +----+----------+-----+-----------+--------+ | 1 | Ramesh | 32 | Ahmedabad | 2000 | | 2 | Khilan | 25 | Delhi | 1500 | | 3 | Kaushik | 23 | Kota | 2000 | | 4 | Chaitali | 25 | Mumbai | 6500 | | 5 | Hardik | 27 | Bhopal | 8500 | +----+----------+-----+-----------+--------+
mysql> BEGIN; mysql> DELETE FROM CUSTOMERS WHERE ID=4; mysql> DELETE FROM CUSTOMERS WHERE ID=5; mysql> ROLLBACK; mysql> SELECT * FROM CUSTOMERS; +----+----------+-----+-----------+--------+ | id | name | age | address | salary | +----+----------+-----+-----------+--------+ | 1 | Ramesh | 32 | Ahmedabad | 2000 | | 2 | Khilan | 25 | Delhi | 1500 | | 3 | Kaushik | 23 | Kota | 2000 | | 4 | Chaitali | 25 | Mumbai | 6500 | | 5 | Hardik | 27 | Bhopal | 8500 | +----+----------+-----+-----------+--------+您看,回滚事务以后,物理数据库中的数据并没有发生改变,表中的内容和事务执行之前的内容一致。
SAVEPOINT point_name;
point_name 为标记点名字。ROLLBACK TO point_name;
+----+----------+-----+-----------+--------+ | id | name | age | address | salary | +----+----------+-----+-----------+--------+ | 1 | Ramesh | 32 | Ahmedabad | 2000 | | 2 | Khilan | 25 | Delhi | 1500 | | 3 | Kaushik | 23 | Kota | 2000 | | 4 | Chaitali | 25 | Mumbai | 6500 | | 5 | Hardik | 27 | Bhopal | 8500 | +----+----------+-----+-----------+--------+
mysql> BEGIN; mysql> DELETE FROM CUSTOMERS WHERE ID=4; mysql> SAVEPOINT sp; mysql> DELETE FROM CUSTOMERS WHERE ID=5; mysql> ROLLBACK TO sp; mysql> SELECT * FROM CUSTOMERS; +----+---------+-----+-----------+--------+ | id | name | age | address | salary | +----+---------+-----+-----------+--------+ | 1 | Ramesh | 32 | Ahmedabad | 2000 | | 2 | Khilan | 25 | Delhi | 1500 | | 3 | Kaushik | 23 | Kota | 2000 | | 5 | Hardik | 27 | Bhopal | 8500 | +----+---------+-----+-----------+--------+您看,我们回滚到标记点 sp,只有 ID 为 4 的用户被删除,ID 为 5 的用户依然留在数据库中。