您的当前位置:首页正文

Oracle事务隔离级别处理差异

2023-11-10 来源:帮我找美食网

Oracle事务隔离是事务读操作不同程度的数据隔离,分为READ_UNCOMMITTED、READ_COMMITTED(默认)、SERIALIZABLE。Oracle事务隔离级别SERIALIZABLE,解决脏读、不重复读、幻读两个事务同时update相同记录时,第一个事务可执行,第二个事务阻塞,当第一个事务提交后,第二个事务抛出异常如图1。当第一个事务回滚后,第二个事务继续执行。 图1

技术分享

Oracle事务隔离级别READ_COMMITTED,解决脏读两个事务同时update相同记录时,第一个事务可执行,第二个事务阻塞,当第一个事务提交后和回滚后,第二个事务继续执行。

Oracle事务隔离级别处理差异

标签:隔离   解决   级别   回滚   不重复   date   margin   技术分享   comm   

小编还为您整理了以下内容,可能对您也有帮助:

oracle 数据库隔离级别学习

oracle
事务隔离级别
事务不同引发的状况:
脏读(Dirty
reads)
一个事务读取另一个事务尚未提交的修改时,产生脏读
很多数据库允许脏读以避免排它锁的竞争。
不可重复读(Nonrepeatable
reads)
同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生非重复读。
幻读(Phantom
reads)
同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻像读。
数据库操作的隔离级别
未提交读(read
uncommitted)
提交读(read
committed)
重复读(repeatable
read)
序列化(serializable)
oracle默认隔离级别read
committed
(statement
level
serialization)
每一个语句,在语句开始时,会获取一个此刻的数据快照。
一个事务有多条语句,如果语句之间存在其它完成的事务,这可能引起不可持续读和幻读。
新建一个测试表books:
name,code,price三个字段
添加两条测试数据
使用pl/sql和java程序模拟并发
不允许脏读测试:
程序段首先查询code是qqq的书的价格
复制代码
代码如下:
//获取连接
省略 
pstat
=
conn.prepareStatement("select
price
from
books
where
code='qqq'"); 
rs
=
pstat.executeQuery(); 
while(rs.next()){ 
 
System.out.println("price:"+rs.getDouble(1)); 

close();
输出结果:price:15.0
然后pl/sql执行更新
复制代码
代码如下:
update
books
set
price=18
where
code='qqq';
!pl/sql设置成手动更新,不自动更新
在执行上面java查询代码
输出仍是price:15.0,说明读不到pl/sql中未提交的执行结果,即不允许脏读
pl/sql
执行
commit;
在执行java查询:
输出结果:price:18.0
会有不可重复读何幻读的现象发生就不用测试了吧,
这两种现象都是针对提交后事物的读引起的,read
commited隔离级别是允许对提交后
的事物进行读的。
隔离级别:重复读(repeatable
read)
这个不允许脏读,不可重复读,但是会有幻读现象。
这个oracle不支持,不好测试。
理解的话就是如果一条查询语句查询的内容有其它事物正在更新的时候,这
查询处于等待状态,直到先前事物提交更新后,才会执行本条查询。也就是
查询的时候也会有锁,需要等待并发的事物释放锁。然后自己获取到锁,执行
自己事物。这样查询也加锁,并发性更低
select
...
for
update
就是这样可以避免不可重复读的发生
隔离级别:serializable
这个就更严格了,事物执行是一个一个的。一个事务中的语句共享同一个数据快照(在事务开始时存在的数据)。
是事物级别的,脏读,不可重复读,幻读根本就没有机会发生。
前面像read
committed都是语句级别的,以语句为单元。
比如
read
committed一个事物A有a(select),b(select),c(update)三条语句
当A事物执行a,b的时候,若有B事物执行更新操作,是有可能的
因为a,b是不加锁的
例子:
复制代码
代码如下:
//获取连接和关闭连接代码
省略 
//不自动提交 
conn.setAutoCommit(false); 
/**
 *
a
查询
 */ 
pstat
=
conn.prepareStatement("select
price
from
books
where
code='qqq'"); 
rs
=
pstat.executeQuery(); 
while(rs.next()){ 
   
//输出
price:25.0 
   
System.out.println("price:"+rs.getDouble(1)); 

close(); 
/**
 *
暂停一会,用pl/sql执行B事务
 *
update
books
set
price=15
where
code='qqq';
 *
commit;
 */ 
Thread.sleep(10000); 
/**
 *
如果这里再执行a查询的话,和第一次查询结果就不一样,因为中间有B事务的提交更新
 *
修改,这也是不可重复读
 */ 
//b
更新 
pstat
=
conn.prepareStatement("update
books
set
price=price+10
where
code='qqq'"); 
pstat.executeUpdate(); 
close(); 
//c
查询 
pstat
=
conn.prepareStatement("select
price
from
books
where
code='qqq'"); 
rs
=
pstat.executeQuery(); 
while(rs.next()){ 
   
//输出
还是price:25.0
,因为B事务的干预 
   
System.out.println("price:"+rs.getDouble(1)); 

close(); 
//提交事务 
conn.commit(); 
if(conn
!=
null){ 
   
conn.close(); 
}
上面执行的顺序,事务B是在A的执行过程中执行的。
以上通过实例介绍了oracle数据库隔离级别的相关内容,希望对大家有所帮助。
下面是一些补充:
数据库中的事务基本作用是将数据库从一致状态转换到另一种一致状态,那么事务隔离级别就是定义了一个事务对于另外一个事务做出的修改有多“敏感”。也就是不同的隔离级别定义了事务相互影响的程度,下面分别介绍一下几种不同的隔离级别。
1.
READ
UNCOMMITTED
其实,oracle不支持这种隔离级别。这种隔离级别允许脏读(也就是可以读取到用户未提交的数据),支持这种隔离级别的数据库主要是为了支持非阻塞读,但是oracle默认支持非阻塞读,所以oracle里面不支持这种隔离级别。下面举一个例子:
如上图所示,假设某一家银行要统计所有账号总共有多少金额。事务A负责统计,事务A从第一行开始读取。假设读取到100行的时候,事务B从账号123转了400元到账户987(事务B还未提交),支持脏读的数据库当事务A读取到342023行的时候,就会得到500元,从而多加了400元。
2.
READ
COMMITTED
这种隔离级别指的是,事务只能读取已经提交的数据,(但是支持可重复读与幻想读)是oracle数据库默认的隔离模式。其实这种隔离级别在别的数据库里面可能还是会“退化”得像脏读一样。就看前面那个例子,假设在事务A读取到342023行前,事务B提前锁定了这一行,并将金额由100改成了500。那么事务A读取到这一行的时候,发现已经被其他事务锁定了,于是进行等待,直到事务B提交。但是当事务B提交之后,事务A还是读取到了500这一个错误信息,这样就和脏读一样的了,而且还让用户等待这个错误的答案。
3.
REPEATABLE
READ
这种隔离级别不支持脏读,不支持可重复读,支持幻想读。主要是为了得到一致性的答案与防止丢失更新。  
a.
得到一致性答案
在oracle里面这个通过多版本机制得到了实现,但是在其他的数据库需要通过加锁机制进行控制,就以上一个例子为例,怎样才能统计出正确的总金额呢,事务A在读取每一行的时候,给每一行加上共享读锁,这样当事务B执行从账号123转400元到账户987的时候。先是操作第一行将账户123的金额由500修改成100,但是第一行已经被事务A锁定,于是等待,这样事务A能够读取到正确的数据。但是如果事务B执行的操作是从账户987转50元到账户123的时候,事务B先操作第342023行,发现没有被锁定,于是锁定将金额由100修改成50,然后操作第一行,发现锁定了于是等待。而事务A读取到342023行的时候,发现这一行已经被事务B锁定于是等待,这样就陷入了死锁。
b.
丢失更新
在采用共享读锁的数据库中,这种隔离级别可以防止丢失更新,比如事务1先读取了第A行然后修改了这一行的C列(其他列也修改了只是值还和以前一样,因为程序员都是整行的更新)。这个时候事务2想也想修改A行的时候会被阻塞,防止事务1的更新被覆盖。
4.
SEAIALIZABLE
不允许脏读,重复读与幻想读,最高的隔离级别。这种隔离级别标明事务A在操作数据库的时候好像就只有事务A在操作,没有其他事务在操作数据库一样。
Oracle
中是这样实现
SERIALIZABLE
事务的:原本通常在语句级得到的读一致性现在可以扩展到事务级。也就是在事务执行的那一刻,将这个事务将要操作的数据拍了一张照片。
从上面的例子我们可以看出,其他数据库采用共享读锁来解决统计总金额问题是没有oracle多版本机制灵活的,其一严重影响了程序的并发性,读阻塞了写。其二可能引起死锁。

oracle 数据库隔离级别学习

oracle
事务隔离级别
事务不同引发的状况:
脏读(Dirty
reads)
一个事务读取另一个事务尚未提交的修改时,产生脏读
很多数据库允许脏读以避免排它锁的竞争。
不可重复读(Nonrepeatable
reads)
同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生非重复读。
幻读(Phantom
reads)
同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻像读。
数据库操作的隔离级别
未提交读(read
uncommitted)
提交读(read
committed)
重复读(repeatable
read)
序列化(serializable)
oracle默认隔离级别read
committed
(statement
level
serialization)
每一个语句,在语句开始时,会获取一个此刻的数据快照。
一个事务有多条语句,如果语句之间存在其它完成的事务,这可能引起不可持续读和幻读。
新建一个测试表books:
name,code,price三个字段
添加两条测试数据
使用pl/sql和java程序模拟并发
不允许脏读测试:
程序段首先查询code是qqq的书的价格
复制代码
代码如下:
//获取连接
省略 
pstat
=
conn.prepareStatement("select
price
from
books
where
code='qqq'"); 
rs
=
pstat.executeQuery(); 
while(rs.next()){ 
 
System.out.println("price:"+rs.getDouble(1)); 

close();
输出结果:price:15.0
然后pl/sql执行更新
复制代码
代码如下:
update
books
set
price=18
where
code='qqq';
!pl/sql设置成手动更新,不自动更新
在执行上面java查询代码
输出仍是price:15.0,说明读不到pl/sql中未提交的执行结果,即不允许脏读
pl/sql
执行
commit;
在执行java查询:
输出结果:price:18.0
会有不可重复读何幻读的现象发生就不用测试了吧,
这两种现象都是针对提交后事物的读引起的,read
commited隔离级别是允许对提交后
的事物进行读的。
隔离级别:重复读(repeatable
read)
这个不允许脏读,不可重复读,但是会有幻读现象。
这个oracle不支持,不好测试。
理解的话就是如果一条查询语句查询的内容有其它事物正在更新的时候,这
查询处于等待状态,直到先前事物提交更新后,才会执行本条查询。也就是
查询的时候也会有锁,需要等待并发的事物释放锁。然后自己获取到锁,执行
自己事物。这样查询也加锁,并发性更低
select
...
for
update
就是这样可以避免不可重复读的发生
隔离级别:serializable
这个就更严格了,事物执行是一个一个的。一个事务中的语句共享同一个数据快照(在事务开始时存在的数据)。
是事物级别的,脏读,不可重复读,幻读根本就没有机会发生。
前面像read
committed都是语句级别的,以语句为单元。
比如
read
committed一个事物A有a(select),b(select),c(update)三条语句
当A事物执行a,b的时候,若有B事物执行更新操作,是有可能的
因为a,b是不加锁的
例子:
复制代码
代码如下:
//获取连接和关闭连接代码
省略 
//不自动提交 
conn.setAutoCommit(false); 
/**
 *
a
查询
 */ 
pstat
=
conn.prepareStatement("select
price
from
books
where
code='qqq'"); 
rs
=
pstat.executeQuery(); 
while(rs.next()){ 
   
//输出
price:25.0 
   
System.out.println("price:"+rs.getDouble(1)); 

close(); 
/**
 *
暂停一会,用pl/sql执行B事务
 *
update
books
set
price=15
where
code='qqq';
 *
commit;
 */ 
Thread.sleep(10000); 
/**
 *
如果这里再执行a查询的话,和第一次查询结果就不一样,因为中间有B事务的提交更新
 *
修改,这也是不可重复读
 */ 
//b
更新 
pstat
=
conn.prepareStatement("update
books
set
price=price+10
where
code='qqq'"); 
pstat.executeUpdate(); 
close(); 
//c
查询 
pstat
=
conn.prepareStatement("select
price
from
books
where
code='qqq'"); 
rs
=
pstat.executeQuery(); 
while(rs.next()){ 
   
//输出
还是price:25.0
,因为B事务的干预 
   
System.out.println("price:"+rs.getDouble(1)); 

close(); 
//提交事务 
conn.commit(); 
if(conn
!=
null){ 
   
conn.close(); 
}
上面执行的顺序,事务B是在A的执行过程中执行的。
以上通过实例介绍了oracle数据库隔离级别的相关内容,希望对大家有所帮助。
下面是一些补充:
数据库中的事务基本作用是将数据库从一致状态转换到另一种一致状态,那么事务隔离级别就是定义了一个事务对于另外一个事务做出的修改有多“敏感”。也就是不同的隔离级别定义了事务相互影响的程度,下面分别介绍一下几种不同的隔离级别。
1.
READ
UNCOMMITTED
其实,oracle不支持这种隔离级别。这种隔离级别允许脏读(也就是可以读取到用户未提交的数据),支持这种隔离级别的数据库主要是为了支持非阻塞读,但是oracle默认支持非阻塞读,所以oracle里面不支持这种隔离级别。下面举一个例子:
如上图所示,假设某一家银行要统计所有账号总共有多少金额。事务A负责统计,事务A从第一行开始读取。假设读取到100行的时候,事务B从账号123转了400元到账户987(事务B还未提交),支持脏读的数据库当事务A读取到342023行的时候,就会得到500元,从而多加了400元。
2.
READ
COMMITTED
这种隔离级别指的是,事务只能读取已经提交的数据,(但是支持可重复读与幻想读)是oracle数据库默认的隔离模式。其实这种隔离级别在别的数据库里面可能还是会“退化”得像脏读一样。就看前面那个例子,假设在事务A读取到342023行前,事务B提前锁定了这一行,并将金额由100改成了500。那么事务A读取到这一行的时候,发现已经被其他事务锁定了,于是进行等待,直到事务B提交。但是当事务B提交之后,事务A还是读取到了500这一个错误信息,这样就和脏读一样的了,而且还让用户等待这个错误的答案。
3.
REPEATABLE
READ
这种隔离级别不支持脏读,不支持可重复读,支持幻想读。主要是为了得到一致性的答案与防止丢失更新。  
a.
得到一致性答案
在oracle里面这个通过多版本机制得到了实现,但是在其他的数据库需要通过加锁机制进行控制,就以上一个例子为例,怎样才能统计出正确的总金额呢,事务A在读取每一行的时候,给每一行加上共享读锁,这样当事务B执行从账号123转400元到账户987的时候。先是操作第一行将账户123的金额由500修改成100,但是第一行已经被事务A锁定,于是等待,这样事务A能够读取到正确的数据。但是如果事务B执行的操作是从账户987转50元到账户123的时候,事务B先操作第342023行,发现没有被锁定,于是锁定将金额由100修改成50,然后操作第一行,发现锁定了于是等待。而事务A读取到342023行的时候,发现这一行已经被事务B锁定于是等待,这样就陷入了死锁。
b.
丢失更新
在采用共享读锁的数据库中,这种隔离级别可以防止丢失更新,比如事务1先读取了第A行然后修改了这一行的C列(其他列也修改了只是值还和以前一样,因为程序员都是整行的更新)。这个时候事务2想也想修改A行的时候会被阻塞,防止事务1的更新被覆盖。
4.
SEAIALIZABLE
不允许脏读,重复读与幻想读,最高的隔离级别。这种隔离级别标明事务A在操作数据库的时候好像就只有事务A在操作,没有其他事务在操作数据库一样。
Oracle
中是这样实现
SERIALIZABLE
事务的:原本通常在语句级得到的读一致性现在可以扩展到事务级。也就是在事务执行的那一刻,将这个事务将要操作的数据拍了一张照片。
从上面的例子我们可以看出,其他数据库采用共享读锁来解决统计总金额问题是没有oracle多版本机制灵活的,其一严重影响了程序的并发性,读阻塞了写。其二可能引起死锁。

事务隔离级别是什么?

事务隔离级别是为了保证并发读取数据库中数据正确性而采用的一种策略。

事务隔离级别包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。

事务的隔离级别有四种级别,读取未提交内容,在该隔离级别,所有事务都可以看到其他未提交事务的执行结果、读取提交内容,这是大多数数据库系统的默认隔离级别。

可重读,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行、可串行化,这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突。

事务隔离的解决方法:

1、未授权读取的方法,也称为读未提交。该隔离级别可以通过“排他写锁”实现。

2、授权读取的方法,可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。

3、可重复读取,通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。

4、序列化的方式。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。

以上内容参考:百度百科-事务隔离级别

事务隔离级别是什么?

事务隔离级别是为了保证并发读取数据库中数据正确性而采用的一种策略。

事务隔离级别包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。

事务的隔离级别有四种级别,读取未提交内容,在该隔离级别,所有事务都可以看到其他未提交事务的执行结果、读取提交内容,这是大多数数据库系统的默认隔离级别。

可重读,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行、可串行化,这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突。

事务隔离的解决方法:

1、未授权读取的方法,也称为读未提交。该隔离级别可以通过“排他写锁”实现。

2、授权读取的方法,可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。

3、可重复读取,通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。

4、序列化的方式。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。

以上内容参考:百度百科-事务隔离级别

事务隔离的四个级别是什么?

事务隔离的四个级别是未提交读(Read Uncommitted)、提交读(Read Committed)、可重复读(Repeable Read)、可串行化(Serializable)。

1、未提交读(Read Uncommitted):事务可以读取未提交的数据,也称作脏读(Dirty Read)。一般很少使用。

2、提交读(Read Committed):是大都是DBMS(如:Oracle,SQLServer)默认事务隔离。执行两次同意的查询却有不同的结果,也叫不可重复读。

3、可重复读(Repeable Read):是MySQL默认事务隔离级别。能确保同一事务多次读取同一数据的结果是一致的。可以解决脏读的问题,但理论上无法解决幻读(Phantom Read)的问题。

4、可串行化(Serializable):是最高的隔离级别。强制事务串行执行,会在读取的每一行数据上加锁,这样虽然能避免幻读的问题,但也可能导致大量的超时和锁争用的问题。很少会应用到这种级别,只有在非常需要确保数据的一致性且可以接受没有并发的应用场景下才会考虑。

事务隔离级别特点比较

从事务隔离级别的定义上可以看出,Serializable级别隔离性最高,但是其效率也最低,因为其要求所有操作相同记录的事务都串行的执行。

对于MySql而言,其默认事务级别是Repeatable read,虽然在定义上讲,这种隔离级别无法解决幻读的问题,但是MySql使用了一种Next key-lock的算法来实现Repeatable read,这种算法是能够解决幻读问题的。

关于Next key-lock算法,在进行查询时,其不仅会将当前的操作记录锁住,也会将查询所涉及到的范围锁住。

也就是说,其他事务如果想要在当前事务查询的范围内进行数据操作,那么其是会被阻塞的,因而MySql在Repeatable read隔离级别下就已经具备了Serializable隔离级别的事务隔离性。

以上内容参考:百度百科-隔离级别

事务隔离的四个级别是什么?

事务隔离的四个级别是未提交读(Read Uncommitted)、提交读(Read Committed)、可重复读(Repeable Read)、可串行化(Serializable)。

1、未提交读(Read Uncommitted):事务可以读取未提交的数据,也称作脏读(Dirty Read)。一般很少使用。

2、提交读(Read Committed):是大都是DBMS(如:Oracle,SQLServer)默认事务隔离。执行两次同意的查询却有不同的结果,也叫不可重复读。

3、可重复读(Repeable Read):是MySQL默认事务隔离级别。能确保同一事务多次读取同一数据的结果是一致的。可以解决脏读的问题,但理论上无法解决幻读(Phantom Read)的问题。

4、可串行化(Serializable):是最高的隔离级别。强制事务串行执行,会在读取的每一行数据上加锁,这样虽然能避免幻读的问题,但也可能导致大量的超时和锁争用的问题。很少会应用到这种级别,只有在非常需要确保数据的一致性且可以接受没有并发的应用场景下才会考虑。

事务隔离级别特点比较

从事务隔离级别的定义上可以看出,Serializable级别隔离性最高,但是其效率也最低,因为其要求所有操作相同记录的事务都串行的执行。

对于MySql而言,其默认事务级别是Repeatable read,虽然在定义上讲,这种隔离级别无法解决幻读的问题,但是MySql使用了一种Next key-lock的算法来实现Repeatable read,这种算法是能够解决幻读问题的。

关于Next key-lock算法,在进行查询时,其不仅会将当前的操作记录锁住,也会将查询所涉及到的范围锁住。

也就是说,其他事务如果想要在当前事务查询的范围内进行数据操作,那么其是会被阻塞的,因而MySql在Repeatable read隔离级别下就已经具备了Serializable隔离级别的事务隔离性。

以上内容参考:百度百科-隔离级别

事务的隔离级别有哪些

大多数的数据库默认隔离级别为:Read Commited 比如 sql server、Oracle少数数据库默认隔离级别为:Repeatable Read 比如: MySql InnoDB 1、脏读:(事务没有提交,提前读取) :当一个事务正在访问数据库,并且对数据进行修改 而这种修改还没有提交到数据库中,这是,另外一个事物访问数据库,然后使用了这个数据。 2、不可重复读(两次读的数据不一致) 一个事务内,多次读同一个数据,在这个事务还没有结束时,另外一个事务也访问该同一个数据,那么在一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次分别读取的数据可能会不一样,这样就发生了一个事务内两次读到的数据不一致。 3、幻读:当事务不是执行时发生的一种现象,例如:第一个事务对一个表中的数据进行修改,这种修改涉及到表中的全部数据行,同时,第二个事务也修改这个表中的数据,这种修改时向表中插入一行新数据,那么以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好像幻觉一样。 4.第一类更新丢失(回滚丢失):

当2个事务更新相同的数据源,如果第一个事务被提交,而另外一个事务却被撤销,那么会连同第一个事务所做的跟新也被撤销。也就是说第一个事务做的跟新丢失了。

5.第二类更新丢失(覆盖丢失):

第二类更新丢失实在实际应用中经常遇到的并发问题,他和不可重复读本质上是同一类并发问题,通常他被看做不可重复读的特例:当2个或这个多个事务查询同样的记录然后各自基于最初的查询结果更新该行时,会造成第二类丢失更新。因为每个事务都不知道不知道其他事务的存在,最后一个事务对记录做的修改将覆盖其他事务对该记录做的已提交的跟新... Isolation (隔离)属性一共支持五种事务设置,具体介绍如下:

DEFAULT (默认)使用数据库设置的隔离级别,由 DBA 默认的设置来决定隔离级别 .

READ_UNCOMMITTED 会出现脏读、不可重复读、幻读 ( 隔离级别最低,并发性能高 )

READ_COMMITTED 会出现不可重复读、幻读问题(锁定正在读取的行)

REPEATABLE_READ 会出幻读(锁定所读取的所有行)

SERIALIZABLE 保证所有的情况不会发生(锁表)

不可重复读的重点是修改 :

同样的条件 , 你读取过的数据 , 再次读取出来发现值不一样了

幻读的重点在于新增或者删除同样的条件 , 第 1 次和第 2 次读出来的记录数不一样

数据库事务隔离级别有哪些

数据库事务隔离级别有哪些如下:

事务的隔离级别有4种,由低到高分别为Read uncommitted 、Read committed 、Repeatable read 、Serializable 。事物的并发操作中可能休闲脏读,不可重复读,幻读。

1、第一种隔离级别:Read uncommitted(读未提交)

如果一个事务已经开始写数据,则另外一个事务不允许同时进行写操作,但允许其他事务读此行数据,该隔离级别可以通过“排他写锁”,但是不排斥读线程实现。这样就避免了更新丢失,却可能出现脏读,也就是说事务B读取到了事务A未提交的数据。

解决了更新丢失,但还是可能会出现脏读。

2、第二种隔离级别:Read committed(读提交)

如果是一个读事务(线程),则允许其他事务读写,如果是写事务将会禁止其他事务访问该行数据,该隔离级别避免了脏读,但是可能出现不可重复读。事务A事先读取了数据,事务B紧接着更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。

解决了更新丢失和脏读问题。

3、第三种隔离级别:Repeatable read(可重复读取)

可重复读取是指在一个事务内,多次读同一个数据,在这个事务还没结束时,其他事务不能访问该数据,这样就可以在同一个事务内两次读到的数据是一样的,因此称为是可重复读隔离级别,读取数据的事务将会禁止写事务,写事务则禁止任何其他事务,这样避免了不可重复读和脏读,但是有时可能会出现幻读。

读取数据的事务可以通过“共享读镜”和“排他写锁”实现。

解决了更新丢失、脏读、不可重复读、但是还会出现幻读。

4、第四种隔离级别:Serializable(可序化)

提供严格的事务隔离,它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行,如果仅仅通过“行级锁”是无法实现序列化的,必须通过其他机制保证新插入的数据不会被执行查询操作的事务访问到。

Top