今天被人问了一个Oracle 关于事务的简单问题,结果本身一时间居然说错了 死了死了的,只能说本身没有用心去理解这个问题。 html
找了一下别人的解释贴这里更直观 java
------------------------------------------------------------------------------------------------------------------------------------ 数据库
1, 脏读 spa
一个事务读到另外一个事务,还没有提交的修改,就是脏读。这里所谓的修改,除了Update操做,不要忘了,还包括
Insert和Delete操做。 .net
脏读的后果:若是后一个事务回滚,那么它所作的修改,通通都会被撤销。前一个事务读到的数据,就是垃圾数据。 htm
举个例子:预订房间。
有一张Reservation表,往表中插入一条记录,来订购一个房间。 blog
事务1:在Reservation表中插入一条记录,用于预订99号房间。 接口
事务2:查询,还没有预约的房间列表,由于99号房间,已经被事务1预订。因此不在列表中。 事务
事务1:信用卡付款。因为付款失败,致使整个事务回滚。
因此插入到Reservation 表中的记录并不置为持久(即它将被删除)。 get
如今99号房间则为可用。
因此,事务2所用的是一个无效的房间列表,由于99号房间,已经可用。若是它是最后一个没有被预约的房间,那么这将是一个严重的失误。
注:脏读的后果很严重。
2,不可重复读。
在同一个事务中,再次读取数据时【就是你的select操做】,所读取的数据,和第1次读取的数据,不同了。就是不可重复读。
举个例子:
事务1:查询有双人床房间。99号房间,有双人床。
事务2:将99号房间,改为单人床房间。
事务1:再次执行查询,请求全部双人床房间列表,99号房间再也不列表中了。也就是说,
事务1,能够看到其余事务所作的修改。
在不可重复读,里面,能够看到其余事务所作的修改,而致使2次的查询结果再也不同样了。
这里的修改,是提交过的。也能够是没有提交的,这种状况同时也是脏读。
若是,数据库系统的隔离级别。容许,不可重复读。那么你启动一个事务,并作一个select查询操做。
查询到的数据,就有可能,和你第2次,3次...n次,查询到的数据不同。通常状况下,你只会作一次,select
查询,并以这一次的查询数据,做为后续计算的基础。由于容许出现,不可重复读。那么任何
时候,查询到的数据,都有可能被其余事务更新,查询的结果将是不肯定的。
注:若是容许,不可重复读,你的查询结果,将是不肯定的。一个不肯定的结果,你能容忍吗?
3,幻读
事务1读取指定的where子句所返回的一些行。而后,事务2插入一个新行,这个新行也知足事务1使用的查询
where子句。而后事务1再次使用相同的查询读取行,可是如今它看到了事务2刚插入的行。这个行被称为幻象,
由于对事务1来讲,这一行的出现是难以想象的。
举个例子:
事务1:请求没有预约的,双人床房间列表。
事务2:向Reservation表中插入一个新纪录,以预订99号房间,并提交。
事务1:再次请求有双人床的未预约的房间列表,99号房间,再也不位于列表中。
注:幻读,针对的是,Insert操做。若是事务2,插入的记录,没有提交。那么同时也是脏读。
Spring在TransactionDefinition接口中定义这些属性
在TransactionDefinition接口中定义了五个不一样的事务隔离级别
ISOLATION_DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应
ISOLATION_READ_UNCOMMITTED 这是事务最低的隔离级别,它充许别外一个事务能够看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读
ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才能被另一个事务读取。另一个事务不能读取该事务未提交的数据。这种事务隔离级别能够避免脏读出现,可是可能会出现不可重复读和幻像读。
ISOLATION_REPEATABLE_READ 这种事务隔离级别能够防止脏读,不可重复读。可是可能出现幻像读。它除了保证一个事务不能读取另外一个事务未提交的数据外,还保证了避免下面的状况产生(不可重复读)。
ISOLATION_SERIALIZABLE 这是花费最高代价可是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。
在TransactionDefinition接口中定义了七个事务传播行为。
PROPAGATION_REQUIRED 若是存在一个事务,则支持当前事务。若是没有事务则开启一个新的事务。
PROPAGATION_SUPPORTS 若是存在一个事务,支持当前事务。若是没有事务,则非事务的执行。可是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少量不一样。
PROPAGATION_MANDATORY 若是已经存在一个事务,支持当前事务。若是没有一个活动的事务,则抛出异常。
PROPAGATION_REQUIRES_NEW 老是开启一个新的事务。若是一个事务已经存在,则将这个存在的事务挂起。
PROPAGATION_NOT_SUPPORTED 老是非事务地执行,并挂起任何存在的事务。
PROPAGATION_NEVER 老是非事务地执行,若是存在一个活动事务,则抛出异常
PROPAGATION_NESTED若是一个活动的事务存在,则运行在一个嵌套的事务中. 若是没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行
资料连接
http://blog.csdn.net/xifeijian/article/details/20313977