Sql事物

一、理解事物

对于一个软件开发人员而言,我们对数据的操作并不会是简单的插入一条语句和查询一条语句,通常我们一次任务就需要执行好几条sql,我们把完成一个任务的一个完整的过程称为一个事物。例如:客户的一次转帐对数据库而言就是一个事物。

事物由一组DML语句组成,用于完成一个相对完整的功能。其实在数据库中,我们执行一条语句去改变数据,在提交事物前数据库并不会直接改变数据,而是只影响了缓冲区,当我们执行了提交事物之后,数据库才会真正的改变数据,你可能会疑问,我执行sql语句也没有提交事物啊,那时因为在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务,并且Mysql这些数据库默认自动提交事务。也就是说事物保证了我们操作的完整性,拿转账而言,整个转账过程是一个事物,该事物由减少账户A余额、增加账户B余额和记录交易信息三部分组成,我们必须保证该事物的三部分均操作完成才算完成整个事物,当某种原因导致该事物中一个操作失败,那么其他操作也会被撤销。

在Mysql中查看是否打开自动提交:


mysql> show variables like 'AUTOCOMMIT';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.01 sec)
--1 或者 ON 表示启用, 0 或者 OFF 表示禁用
mysql> SET AUTOCOMMIT = 0/1; 
--以上命令可以打开和关闭自动提交
二、事物的属性
  • 原子性(Atomicity):一个事物必须保证数据一致,拿转账而言,如果数据不一致,那么这个事物就是没有意义的,一个事物的数据操作必须保持一致,要么全部操作成功,要么全部操作失败。
  • 一致性(Consistency):数据库从一个一致性状态变换到另外一个一致性状态,数据库的完整性不会受到破坏。
  • 隔离性(Isolation):通常来说,一个事务所做的修改在最终提交前,对其他事务是不可见的,也就是说事物之间相互隔离。
  • 持久性(Durability):一旦事务提交,则其所做的修改就会永久保存到数据库中,即使系统故障,修改的数据也不会改变。

以上可见,事物在我们编程中对数据保护由很大作用。

二、事物的分类和控制

1、事物分类
SQL语言按其功能分为四大类:数据查询语言DQL、数据操纵语DML、数据定义语言DDL、数据控制语言DCL。 事务是为了保持数据的一致性, 而数据查询语言只是从数据库中查询数据,不会引起致性问题。所以,根据SQL语言的分类情况,可以将事务分为针对DML
的事务、针对DDL的事务和针对DCL的事务。
当执行第一个DML SQL语句时或一个事务结束之后下一个SQL语句开始时,事务开始。
当碰到一个COMMIT (提交)语句或ROLLBACK (回滚)语句时,事务结束。尤其需要注意的是,DDL语句(例如创建表)和DCL语句(例如给用户授权)执行时自动提交事务,不需要显式提交,在此之前的DML语句也一并被隐式提交。另外,在数据库客户端程序退出或者数据库崩溃时,为了保持数据一致性,也会结束事务。

2、事物控制语句

COMMIT提交当前事物,使之前的操作永久作用于数据库
ROLLBACK回滚当前事物,丢弃(撤回)所有当前未提交操作
SAVEPOINT name在当前事物中标记保存点
ROLLBACK TO name回滚当前事物到指定的保存点从而撤回保存点之后的操作
三、事物操作事例(请先关闭自动提交)

1、COMMIT和ROLLBACK语句
假设需要删除雇员编号为209的雇员,执行下面语句:

DELETE FROM employees WHERE id=209

在新的sql窗口中执行如下代码:

SELECT id,name FROM employees WHERE id=209

此时我们会发现数据库的数据查出来了,也就是说我们的操作并没有永久作用于数据库,我们在原先的数据库操作窗口中执行事物回滚和提交语句:

ROLLBACK;
COMMIT;

在新SQL窗口中,再次在雇员表中查询雇员编号为209的雇员信息,仍然可以查到该雇员信息。原因是先回滚,再提交,删除操作已被取消,编号为209的雇员仍在数据库中。另外,还有一种情况,就是出现了客户端工具意外退出的情况或发生系统故障,此时整个事务会被自动回滚。该回滚防止不必要的数据改变错误发生,保证数据的完整性。
执行DML语句且没有结束事务时,如果需要查询数据库的真实改变情况,则要求在一个新SQL窗口中执行查询语句。为什么这样呢?
因为事务中所做的每个操作在事务被提交之前都是临时的,在COMMIT或ROLLBACK语句执行之前,DML语句首先影响该用户的数据库缓冲区,因此这些操作可以被恢复,而且因为是在该用户的数据缓冲区,所以在原SQL窗口中查询得到的是数据缓冲区的结果,不是数据库真实的数据。要想拿到数据库真实的数据,需要在新SQL窗口中执行查询语句。这样,针对不同的用户,Oracle 服务器用读一致性 来确保每个用户看到的数据和上次提交时的数据相同。
另外,在一个用户执行DML语句(未结束事务)影响数据库中相关的行时,受影响的行被锁定,其他用户不能改变受影响的行中的数据,直到事务结束时为止。

现在我们执行以下语句:

DELETE FORM employees WHERE id=209

此时在一个新窗口执行下面的语句来修改209雇员的姓名:

UPDATE employees SET name=‘张三’ WHERE id=209

我们发现该语句一直在执行但是始终没有结果,这就说明该数据已经被锁定了,原因是前面的删除语句没有完成事物提交。现在我们在原删除语句窗口执行COMMIT;提交事物,在此执行修改雇员姓名语句,我们发现窗口显示0行记录被更新,说明我们前面的删除事物执行结束了,该行已被解锁,但因为数据已经删除,故没有数据被更新。

2、SAVEPOINT语句
在当前事物中用SAVEPOINT name语句创建一个标记,该标记称为保存标记,它可以把事物分成更小的部分,使用ROLLBACK TO name语句,丢弃保存点之后的数据操作,其语法形式如下:

DML A...
SAVEPOINT sp
DML B...
ROLLBACK TO sp

当执行ROLLBACK TO sp语句时,DML B...段语句会被撤销。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值