Oracle数据库事务学习
目录
一、什么是事务,事务的作用是什么
二、事务的四大特性(ACID)
1. 原子性(Atomicity)
2. 一致性(Consistency)
3. 隔离性(Isolation)
4. 持久性(Durability)
三、关于锁的概念——表锁、行锁、死锁、乐观/悲观锁、
1.行锁
2.表锁
3.死锁
4.乐观锁
5.悲观锁
四、查询和杀死进程
一、什么是事务,事务的作用是什么
事务(Transaction)是由一系列操作序列组成的一个逻辑单位,这些操作要么全部成功执行,要么全部不执行。
示例:假设有一个银行系统,用户A想要从自己的账户转账100元到用户B的账户。
需要满足以下条件:
- 用户A的账户必须有足够的余额(至少100元)。
- 用户B的账户必须存在。
- 转账金额不能超过用户A的账户余额。
- 转账成功后,用户A和用户B的账户余额应该更新。
-- 检查用户A的余额是否足够
SELECT balance FROM accounts WHERE user_id = 'A';-- 如果余额足够,执行转账操作
UPDATE accounts SET balance = balance 100 WHERE user_id = 'A';
UPDATE accounts SET balance = balance + 100 WHERE user_id = 'B';
COMMIT; -提交事务
事务确保了在转账过程中数据的一致性和完整性。
如果其中任何一个步骤失败,整个事务将被回滚,以确保数据不会处于不一致的状态。
二、事务的四大特性(ACID)
1. 原子性(Atomicity)
原子性指的是事务中的所有操作要么全部完成,要么全部不完成,不会结束在中间某个点。
例子:向银行账户转账是一个事务。如果转账过程中,账户A的扣款操作成功,但是账户B的存款操作失败,那么整个事务应该回滚到最开始的状态,就好像转账操作从未发生一样。
2. 一致性(Consistency)
一致性确保事务在执行前后,数据库保持一致的状态。事务必须保证数据库从一个有效的状态转移到另一个有效的状态。
例子:在图书馆管理系统中,借书是一个事务。
如果一个用户尝试借阅一本已被借出的书,这个事务应该被拒绝,以保持数据库中关于书籍可借状态的一致性。
3. 隔离性(Isolation)
隔离性指并发执行的事务之间不会互相影响。每个事务都应该是独立的,就像它是在系统上单独运行一样。
例子:如果两个用户同时尝试购买最后一件商品,数据库需要保证这两个事务是隔离的,以防止库存数量出现不一致的情况。
每个事务都应看到商品的原始数量,并在购买成功后更新库存。
4. 持久性(Durability)
持久性意味着一旦事务被提交,它对数据库的改变就是永久性的,即使系统发生故障也不会丢失。
例子:在电子商务网站中,用户下单是一个事务。
一旦用户提交订单并事务被成功提交,这个订单信息就会永久保存在数据库中,即使随后系统发生崩溃或重启。
这四个特性共同确保了数据库事务的可靠性和数据的完整性。
三、关于锁的概念——表锁、行锁、死锁、乐观/悲观锁、
为了保证数据的一致性,就会把数据给锁起来。
1.行锁
就是把那一行的数据给锁起来,在没有提交或者回滚事务之前,其它的会话(事务)都不能去修改这条数据。
- 行锁允许多个事务同时访问同一张表中的不同行,从而增加数据库的并发性能。这对于OLTP系统尤为重要,其中许多独立事务需要访问和修改数据集的不同部分。
- 当事务执行INSERT、UPDATE、DELETE操作时,Oracle自动为所涉及的行加上锁,保持到事务提交或回滚。此外,使用SELECT ... FOR UPDATE也会对选定行加上锁。
- 行锁主要通过每行的锁定标志位实现,当一个事务需要修改某行数据时,它会改变该行上的锁定标志位,从而获得对该行的独占访问权。
- 行锁主要用于单行或少量行的精确操作,确保操作的原子性和隔离性。与表锁相比,行锁提供了更高的并发性,但管理成本更高。
2.表锁
把整张表给锁起来,在没有提交或者回滚事务之前,不能对这张表的结构做 DDL 操作。
- 表锁是锁定整个表的一种方式,它可以防止其他事务在该表上进行任何数据的增删改操作。这种锁定方式在某些情况下非常有效,比如在大量数据迁移或批量更新时。
- 当执行DDL语句(如ALTER TABLE)或者某些没有使用索引的DML语句(INSERT、UPDATE、DELETE)时,可能会触发表锁。特别是当SQL语句无法精准定位到行级别时,Oracle可能选择表级锁定以维护数据完整性。
- 通过LOCK TABLE语句显式地锁定一张表,这通常用于特定的数据库维护操作,如数据迁移时的一致性保护。
- 表级锁包括多种模式,如行共享(RS)、行独占(RX)、共享锁(S)、共享行排他(SRX)以及独占(X)等。这些锁模式决定了其他事务对这张表能进行哪些操作。
3.死锁
两个事务之间都在等待着对方解锁,释放资源。
-死锁的处理:当两个或多个事务彼此等待对方释放锁时,会发生死锁。Oracle会自动检测并解决死锁,通常通过终止其中一个事务来解除死锁状态。
-事务设计:良好的事务设计应避免不必要的锁升级,优先使用行级锁,减少锁持有时间,合理设计事务大小和持续时间,以优化性能并减少锁相关的问题。
4.乐观锁
乐观锁和悲观锁,他们也是锁,区别就是在修改数据的时候是否马上把这一条数据给锁起来。
事务1在对一条数据做修改的时候,数据库就很乐观地认为其它事务不会会对这条数据做修改,所以数据库就不会把那张表和那条数据给锁起来,其它事务是可以执行对这条数据执行 UPDATE,只有在 COMMIT 的时候才会去校验其它事务是否有对该条数据做修改。
乐观锁通常通过在数据表中添加一个版本号或时间戳字段实现。事务开始时记录下当前的版本号,事务提交时检查版本号是否改变,如果改变则说明有其他事务更新了数据。
5.悲观锁
事务1在对一条数据做修改的时候,数据库就很悲观地认为其它事务也会对这条数据做修改,所以数据库就会马上把那张表和那条数据给锁起来,不让其它事务修改它。
悲观锁可以通过数据库的锁机制实现,例如行锁、表锁等。事务在读取数据时即加锁,其他事务必须等待锁释放后才能访问数据。
四、查询和杀死进程
---查进程 在 SYS 用户
select sess.sid,--会话idsess.serial#,lo.oracle_username,lo.os_user_name,ao.object_name,lo.locked_mode
from v$locked_object lo,dba_objects ao,v$session sess
where ao.object_id = lo.object_id and lo.session_id = sess.sid;--杀进程
-alter system kill session 'sid,serial#';alter system kill session '137,1946';