事务的本质
redo log - 重做日志,保存sql语句到一个指定的log文件,先到logbuffer,然后commit或一定条件满足后刷到磁盘/undo log - 回滚日志,将当前要修改的行内容复制到undobuffer,满足一定条件后刷到磁盘,保存在数据文件中
修改一行数据:
先用排他锁锁定该行,记录redolog,把改行修改前的值copy到undolog中,然后修改当前行的值,填写事物编号,并使回滚指针指向undolog中修改前的行
事物隔离级别
感觉这个例子比较通俗https://blog.csdn.net/qq_33290787/article/details/51924963, 基于事物的本质参考:https://blog.csdn.net/chen77716/article/details/6742128,可以增加如下理解
名称 | 解释-t1 | 解释-t2 | |
READ UNCOMMITTED |
读取未提交内容,脏读 读事物直接读取主记录,无论事物是否完成 |
begin transaction update
rollback |
select data |
READ COMMITTED |
读取提交内容 读事物读取最新的undolog,确保可以去到最新的更新,但重复可能会读到不同的值 |
begin transaction update commit
begin transaction update commit |
select data
select data |
REPEATABLE READ |
可重读 读事物读取指定版本号的undolog,确保可以多次重复读取相同的值,但可能读不到最新增加的值,因为insert不会记录undolog |
begin transaction insert value into range commit
begin transaction insert value into range commit |
select data where range
select data where range |
SERIALIZABLE |
可串行化,为每个读数据建立共享锁 锁表 |
完全串行,未提交再操作等待 |
查看oracle数据库隔离级别
首先需要先在事物中,然后用如下sql查看事物隔离级别
select sid,serial#,flag,
CASE WHEN bitand(FLAG,268435456) = 0 THEN 'SERIALIZABLE'
ELSE 'READ COMMITTED'
END AS ISOLATIONLEVEL
from V$transaction t,v$session s
where t.addr=s.taddr
AND audsid = USERENV('SESSIONID');
SID SERIAL# FLAG ISOLATIONLEVEL
---------- ------------- -------- --------------
52 3 3587 SERIALIZABLE
设置oracle数据库隔离级别
SET TRANSACTION ISOLATION LEVEL***