📅  最后修改于: 2020-11-19 00:52:40             🧑  作者: Mango
MySQL中的事务是一组连续的语句,查询或操作,例如选择,插入,更新或删除,以作为可以提交或回滚的单个工作单元执行。如果事务对数据库进行了多次修改,则会发生两件事:
换句话说,如果不完成集合中的每个可用操作,交易就不会成功。这意味着如果任何语句失败,则事务操作将无法产生结果。
MySQL中的事务从第一个可执行的SQL语句开始,并在找到提交或显式或隐式回滚时结束。它显式使用COMMIT或ROLLBACK语句,并且在使用DDL语句时隐式使用。
让我们通过以下解释了解交易的概念。
通过考虑银行数据库,我们可以了解MySQL中事务的概念。假设银行客户希望将钱从一个帐户转移到另一个帐户。我们可以通过使用将分为以下步骤的SQL语句来实现此目的:
该事务主要包含四个属性,称为ACID属性。现在,我们将详细讨论ACID属性。 ACID属性代表:
原子性:此属性确保必须成功执行事务单元内的所有语句或操作。否则,如果任何操作失败,则整个事务将中止,并且它将回滚到其先前状态。它包括以下功能:
一致性:此属性确保仅在成功提交事务时,数据库才会更改状态。它还负责保护数据免于崩溃。它包括以下功能:
隔离:此属性保证事务处理单元中的每个操作独立运行。它还可以确保语句彼此透明。它包括以下功能:
持久性:此属性保证即使系统崩溃或失败,已提交事务的结果也将永久保留。它包括以下功能:
MySQL通过以下语句控制事务:
SET autocommit = 0;
OR,
SET autocommit = OFF:
同样,使用以下语句启用自动提交模式:
SET autocommit = 1;
OR,
SET autocommit = ON:
假设我们有两个名为“员工”和“订单”的表,其中包含以下数据:
表:员工
表:订单
如果要使用事务,则需要将SQL语句分成逻辑部分。之后,我们可以定义是应该提交数据还是回滚数据。
以下步骤说明了如何创建事务:
以下是执行上述操作的命令:
-- 1. Start a new transaction
START TRANSACTION;
-- 2. Get the highest income
SELECT @income:= MAX(income) FROM employees;
-- 3. Insert a new record into the employee table
INSERT INTO employees(emp_id, emp_name, emp_age, city, income)
VALUES (111, 'Alexander', 45, 'California', 70000);
-- 4. Insert a new record into the order table
INSERT INTO Orders(order_id, prod_name, order_num, order_date)
VALUES (6, 'Printer', 5654, '2020-01-10');
-- 5. Commit changes
COMMIT;
下图更清楚地说明了这一点:
我们可以借助下图了解回滚事务。首先,打开MySQL命令提示符,然后使用密码登录数据库服务器。接下来,我们必须选择一个数据库。
假设我们的数据库包含“ Orders”表。现在,以下是执行回滚操作的脚本:
-- 1. Start a new transaction
START TRANSACTION;
-- 2. Delete data from the order table
DELETE FROM Orders;
执行完上面的语句后,我们将获得如下输出,该输出显示表Orders已成功删除的所有记录。
现在,我们需要打开一个单独的MySQL数据库服务器会话,并执行以下语句来验证Orders表中的数据:
SELECT * FROM Orders;
它将给出如下输出。
尽管我们在第一个会话中进行了更改,但是我们仍然可以看到表中的记录可用。这是因为在我们没有在第一个会话中执行COMMIT或ROLLBACK语句之前,更改不是永久的。
因此,如果我们想使更改永久生效,请使用COMMIT语句。否则,请执行ROLLBACK语句以回滚第一个会话中的更改。
-- 3. Rollback changes
ROLLBACK;
-- 4. Verify the records in the first session
SELECT * FROM Orders;
成功执行后,它将产生以下结果,我们可以看到更改已回滚。
使用MySQL Transaction不能回滚的语句。
MySQL Transaction不能回滚所有语句。例如,这些语句包括DDL(数据定义语言)命令,例如CREATE,ALTER或DROP数据库,以及CREATE,UPDATE或DROP表或存储的例程。我们必须确保在设计交易时不包括这些声明。
SAVEPOINT语句使用事务内的标识符名称创建一个特殊标记。它允许回滚保存点之后执行的所有语句。使事务恢复到保存点之前的先前状态。如果我们在当前事务中使用相同的名称设置了多个保存点,则新保存点负责回滚。
ROLLBACK TO SAVEPOINT语句允许我们将所有事务回滚到已建立的给定保存点,而不会中止该事务。
RELEASE SAVEPOINT语句从当前事务中销毁命名的保存点,而不会撤消在建立保存点之后执行的查询的影响。这些语句之后,不会发生任何回滚命令。如果该事务中不存在该保存点,则会产生错误。
以下是MySQL Transaction中上述语句的语法:
SAVEPOINT savepoint_name
ROLLBACK TO [SAVEPOINT] savepoint_name
RELEASE SAVEPOINT savepoint_name
让我们通过示例了解如何使用这些语句。在下面的示例中,我们将使用SAVEPOINT和ROLLBACK TO SAVEPOINT语句,这些语句说明保存点如何确定可以回滚当前事务的哪些记录。
START TRANSACTION;
SELECT * FROM Orders;
INSERT INTO Orders(order_id, prod_name, order_num, order_date)
VALUES (6, 'Printer', 5654, '2020-01-10');
SAVEPOINT my_savepoint;
INSERT INTO Orders(order_id, prod_name, order_num, order_date)
VALUES (7, 'Ink', 5894, '2020-03-10');
ROLLBACK TO SAVEPOINT my_savepoint;
INSERT INTO Orders(order_id, prod_name, order_num, order_date)
VALUES (8, 'Speaker', 6065, '2020-02-18');
COMMIT;
在上面,
以下输出按顺序说明了上述步骤,有助于您轻松理解。
现在,我们将使用SELECT语句来验证上述操作。在输出中,我们可以看到成功添加了order_id = 6和order_id = 8,但是未将order_id = 7插入表中。建立保存点后,它将回滚输入的值:
现在,我们再来看一个示例RELEASE SAVEPOINT,该示例建立my_savepoint,然后删除一个保存点。
START TRANSACTION;
INSERT INTO Orders(order_id, prod_name, order_num, order_date)
VALUES (7, 'Ink', 5894, '2020-03-10');
SAVEPOINT my_savepoint;
UPDATE Orders SET prod_name='Scanner' WHERE order_id=8;
RELEASE SAVEPOINT my_savepoint;
COMMIT;
在输出中,我们可以看到事务中的所有语句都已成功执行。在这里,INSERT和UPDATE语句都在COMMIT修改表。