数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。
一个事务是一个不可分割的工作单位,对于其数据修改,要么全都执行,要么全都不执行。
事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。一致性与原子性是密切相关的。
一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性也称永久性(permanence),事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。
在sql语句结束后,执行commit;
提交刚才执行的语句,完成一次事务
2. 隐式操作
-- on:开启事务自动提交;off:取消自动提交
set autocommit [on | off];
······
当发生以下时间时,事务将结束
commit
/rollback
进行事务的提交和回滚SQL*Plus
,那么正常退出时,事务将会自动提交;而非正常退出时,则事务回滚。在sql语句之后执行rollback;
可将之前所有提交的语句回滚
在事务处理过程中,Oracle会保存事务处理之前数据的映像。在事务处理过程中,会将这个映像提供给查询数据的其他会话。如果出现错误,或者会话故意请求回滚,那么它也可以用来自动回滚事务。
回滚之前数据的状态是,数据已经改变,但反转这些变更所需的信息是可用的。为了满足隔离性原则,会将这些信息提供给其他所有会话。回滚会恢复数据改变之前的映像,从而抛弃所有变更;事务插入的所有行都会删除,事务删除的所有行都会重新插入表中,已经更新的行会回到原始状态。其他会话根本不知道发生了什么,它们绝对看不到这些变更。处理事务的会话现在会将数据看做事务开始之前的数据。
2. 取消部分操作
可以在sql执行过程中加入保存点savepoint point
可在之后的执行过程中回滚到保存点前的状态
update ····;
savepoint insertDemo;
insert into ···;
rollback to insertDemo;
通过rollback to insertDemo
可将数据库回滚insert操作,回到update之后的状态
使用保存点就是允许编程人员在事务中设置一个标记,这个标记可以用来控制ROLLBACK命令的效果。除了回滚整个事务并终止它之外,还可以反转在特定点之后所做的所有变更,同时保持在该点之前所做的变更不变。事务本身继续进行:仍然没有提交,仍然可以回滚,仍然对其他会话不可见。
锁是在事务访问相同资源时,防止事务之间的有害性交互的机制,这些资源包括用户系统对象、内存和数据字典中的共享数据结构。
为什么需要锁:并发运行时,容易造成读取脏数据
并发大概分为几类:
- 读并发(不会造成错误,入select)
- 写并发(容易造成错误,入insert,update,delete)
锁什么时候释放:事务结束
两个客户端同时操作同一数据时,一个进行操作,另一个进行等待
-- 显示加锁
select * from tb_cpc_error_202005 where media_type = 1 for update;
通过select for update
对数据进行加锁,只能当前客户端进行数据操作,其他客户端需要等待该客户端操作结束后再执行。
被称为写锁,该模式下的锁可以防止资源的共享,当进行数据修改时,会启用该类型的锁。
lock table tb_cpc_error_202005 in exclusive mode;
被称为读锁,该模式下的锁锁定的数据只能被读取,而不能被修改。加了共享锁的记录,允许被并发地读取。
lock table tb_cpc_error_202005 in share mode;
当对于数据库某个表的某一列做更新或删除等操作,执行完毕后该条语句不提交,另一条对于这一列数据做更新操作的语句在执行的时候就会处于等待状态,此时的现象是这条语句一直在执行,但一直没有执行成功,也没有报错。
用dba用户执行以下语句
select username,lockwait,status,machine,program
from v$session
where sid in
(
select session_id from v$locked_object
)
如果有输出的结果,则说明有死锁,且能看到死锁的机器是哪一台。字段说明:
字段 | 描述 |
---|---|
Username | 死锁语句所用的数据库用户 |
Lockwait | 死锁的状态,如果有内容表示被死锁 |
Status | 状态,active表示被死锁 |
Machine | 死锁语句所在的机器 |
Program | 产生死锁的语句主要来自哪个应用程序 |
用dbo
用户执行以下语句,可以查看被死锁的语句
select sql_text
from v$sql
where hash_value in
(
select sql_hash_value
from v$session
where sid in
(
select session_id from v$locked_object
)
)