`
sunxboy
  • 浏览: 2825604 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

幻读,重复读,脏读 以及Spring的事务属性说明

阅读更多

设置事务隔离性级别

    1)幻读:事务1读取记录时事务2增加了记录并提交,事务1再次读取时可以看到事务2新增的记录
    2)不可重复读取:事务1读取记录时,事务2更新了记录并提交,事务1再次读取时可以看到事务2修改后的记录
    3)脏读:事务1更新了记录,但没有提交,事务2读取了更新后的行,然后事务T1回滚,现在T2读取无效。    

 

    READ UNCOMMITTED:幻读,不可重复读和脏读均允许;
    READ COMMITTED:允许幻读和不可重复读,但不允许脏读;
    REPEATABLE READ:允许幻读,但不允许不可重复读和脏读;
    SERIALIZABLE:幻读,不可重复读和脏读都不允许

 

    ORACLE默认的是 READ COMMITTED     SET TRANSACTION ISOLATION LEVEL SERIALIZABLE|READ COMMITTED|READUNCOMMITTED|REPEATABLE READ;

 

spring 中一共定义了六种事务传播属性

    PROPAGATION_REQUIRED --支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
 PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。
 PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。
 PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
 PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
 PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
 PROPAGATION_NESTED --如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

  前六个策略类似于EJBCMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
  它要求事务管理器或者使用JDBC 3.0 SavepointAPI提供嵌套事务行为(如Spring的DataSourceTransactionManager)

 

 

 

 

 

 

 

Spring @Transactional属性说明

 

 

 

Propagation

事务传播行为

PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

Isolation

事务隔离级别

@Transactional(isolation = Isolation.READ_UNCOMMITTED)读取未提交数据(会出现脏读, 不可重复读) 基本不使用

@Transactional(isolation = Isolation.READ_COMMITTED)读取已提交数据(会出现不可重复读和幻读)

@Transactional(isolation = Isolation.REPEATABLE_READ)可重复读(会出现幻读)

@Transactional(isolation = Isolation.SERIALIZABLE)串行化

 

 

 

 

 

 

 

 

 

 

Spring事务的传播行为

 

在service类前加上@Transactional,声明这个service所有方法需要事务管理。每一个业务方法开始时都会打开一个事务。

Spring默认情况下会对运行期例外(RunTimeException)进行事务回滚。这个例外是unchecked

如果遇到checked意外就不回滚。

如何改变默认规则:

1 让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)

2 让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)

3 不需要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED)

 

注意: 如果异常被try{}catch{}了,事务就不回滚了,如果想让事务回滚必须再往外抛try{}catch{throw Exception}。

 

spring——@Transactional事务不管理jdbc,所以要自己把jdbc事务回滚。

下面给出了回滚JDBC事务的代码示例:

Java代码
  1. public void processT(String orders) {  
  2. Context initCtx = new InitialContext();  
  3. javax.sql.DataSource ds = javax.sql.DataSource)initCtx.lookup  
  4. (“java:comp/env/jdbc/OrdersDB”);  
  5. java.sql.Connection conn = ds.getConnection();  
  6. try {  
  7. conn.setAutoCommit( false ); //更改JDBC事务的默认提交方式  
  8. orderNo = createOrder( orders );  
  9. updateOrderStatus(orderNo, “orders created”);  
  10. conn.commit(); //提交JDBC事务  
  11. } catch ( Exception e ){  
  12. try {  
  13. conn.rollback(); //回滚sJDBC事务  
  14. throw new EJBException(“事务回滚: “ + e.getMessage());  
  15. } catch ( SQLException sqle ){  
  16. throw new EJBException(“出现SQL操作错误: “ + sqle.getMessage());  
  17. }  
  18. }  

 

下面给出了JTA事务代码示例:

Java代码
  1. public void processOrder(String orderMessage) {  
  2. UserTransaction transaction = mySessionContext.getUserTransaction(); //获得JTA事务  
  3. try {  
  4. transaction.begin(); //开始JTA事务  
  5. orderNo = sendOrder(orderMessage);  
  6. updateOrderStatus(orderNo, “order sent”);  
  7. transaction.commit(); //提交JTA事务  
  8. } catch (Exception e){  
  9. try {  
  10. transaction.rollback(); //回滚JTA事务  
  11. } catch (SystemException se){  
  12. se.printStackTrace();  
  13. }  
  14. throw new EJBException(“事务回滚: “ + e.getMessage());  
  15. }  
  16. }  

 

 

在整个方法运行前就不会开启事务

       还可以加上:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true),这样就做成一个只读事务,可以提高效率。

       各种属性的意义:

       REQUIRED:业务方法需要在一个容器里运行。如果方法运行时,已经处在一个事务中,那么加入到这个事务,否则自己新建一个新的事务。

       NOT_SUPPORTED:声明方法不需要事务。如果方法没有关联到一个事务,容器不会为他开启事务,如果方法在一个事务中被调用,该事务会被挂起,调用结束后,原先的事务会恢复执行。

       REQUIRESNEW:不管是否存在事务,该方法总汇为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务挂起,新的事务被创建。

       MANDATORY:该方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务。如果在没有事务的环境下被调用,容器抛出例外。

       SUPPORTS:该方法在某个事务范围内被调用,则方法成为该事务的一部分。如果方法在该事务范围外被调用,该方法就在没有事务的环境下执行。

       NEVER:该方法绝对不能在事务范围内执行。如果在就抛例外。只有该方法没有关联到任何事务,才正常执行。

       NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务 拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。

 

 

 

 

 

Isolation Level(事务隔离等级)

1、Serializable:最严格的级别,事务串行执行,资源消耗最大;
2、REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。
3、READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。
4、Read Uncommitted:保证了读取过程中不会读取到非法数据。隔离级别在于处理多事务的并发问题。
我们知道并行可以提高数据库的吞吐量和效率,但是并不是所有的并发事务都可以并发运行。
我们首先说并发中可能发生的3中不讨人喜欢的事情
1: Dirty reads--读脏数据。也就是说,比如事务A的未提交(还依然缓存)的数据被事务B读走,如果事务A失败回滚,会导致事务B所读取的的数据是错误的。
2: non-repeatable reads--数据不可重复读。比如事务A中两处读取数据-total-的值。在第一读的时候,total是100,然后事务B就把total的数据改成 200,事务A再读一次,结果就发现,total竟然就变成200了,造成事务A数据混乱。
3: phantom reads--幻象读数据,这个和non-repeatable reads相似,也是同一个事务中多次读不一致的问题。但是non-repeatable reads的不一致是因为他所要取的数据集被改变了(比如total的数据),但是phantom reads所要读的数据的不一致却不是他所要读的数据集改变,而是他的条件数据集改变。比如Select account.id where account.name="ppgogo*",第一次读去了6个符合条件的id,第二次读取的时候,由于事务b把一个帐号的名字由"dd"改成"ppgogo1",结果取出来了7个数据。 

                            Dirty reads  non-repeatable reads phantom reads 
Serializable                 不会             不会                        不会 
REPEATABLE READ  不会             不会                        会 
READ COMMITTED   不会              会                           会 
Read Uncommitted    会                  会                           会 

readOnly
事务属性中的readOnly标志表示对应的事务应该被最优化为只读事务。

分享到:
评论

相关推荐

    spring事务-项目案例-PPT解读.zip

    4.逐个分析脏读,不可重复读和幻读出现的场景和解决方案 5.事务的底层原理(附带流程图) 6.事务的7种传播性、使用场景和实际场景 7.spring事务15种不生效的场景 8.事务的基本属性和常用的属性字段 三、压缩包有...

    spring杂谈 作者zhang KaiTao

    1.1 Spring事务处理时自我调用的解决方案及一些实现方式的风险 1.2 我对AOP的理解 1.3 Spring开闭原则的表现-BeanPostProcessor的扩展点-1 1.4 我对IoC/DI的理解 1.5 SpringMVC + spring3.1.1 + hibernate4.1.0 集成...

    Spring IOC DI AOP 事务)

    目录IOC(控制反转)DI(依赖注入)AOP(面向切面编程)Spring事务事务传播特性脏读,不可重复读,幻读事务隔离级别不喜勿喷 如有雷同请联系本人!! IOC(控制反转) IOC是一种设计思想,而不是什么技术 传统方法...

    Spring面试题

    Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。 ☆ Spring DAO:JDBC DAO 抽象层提供了有意义的异常...

    【分布式事务----LCN】LCN原理及使用方式.docx

    LCN连接重用机制 当模块在同一次事务下被重复执行时,连接资源会被重用,提高连接的使用率。 事务补偿机制 为什么需要事务补偿? 事务补偿是指在执行某个业务方法时,本应该执行成功的操作却因为服务器挂机或者...

    ssh(structs,spring,hibernate)框架中的上传下载

    Struts+Spring+Hibernate实现上传下载    本文将围绕SSH文件上传下载的主题,向您详细讲述如何开发基于SSH的Web程序。SSH各框架的均为当前最新版本:  •Struts 1.2  •Spring 1.2.5  •Hibernate 3.0  本文...

    基于springboot , zookeeper , redis 分布式事务强一致性方案+源代码+文档说明

    FAT ,基于springboot , 使用zookeeper,redis , spring async , spring transactionManager的强一致性分布式事务解决方案 ## 框架介绍 纯编码方式,强一致性。 使用redis/zookeeper作为注册中心 ,代理事务的执行...

    基于Dubbo实现的SOA分布式(没有实现分布式事务)-SpringBoot整合各种组件的JavaWeb脚手架+源代码+文档

    6. 引用application.properties中的属性的方式:@ConfigurationProperties(prefix = "spring.mail") + @Component + setter + getter 7. 引用其他自定义配置文件中的属性的方式: - @Component - ## 项目备注 1...

    springboot参考指南

    在Spring环境中使用YAML暴露属性 iii. 23.6.3. Multi-profile YAML文档 iv. 23.6.4. YAML缺点 vii. 23.7. 类型安全的配置属性 i. 23.7.1. 第三方配置 ii. 23.7.2. 松散的绑定(Relaxed binding) iii. 23.7.3. @...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    脏读、不可重复读、幻读 105 【数据库】索引的结构有哪些? 107 【数据库】乐观锁与悲观锁的区别 107 【数据库】数据库的三范式 107 【数据库】inner/left/right/full join的区别 109 【数据库】哪些字段该添加索引...

    基于maven项目的SSM框架与layu前端框架的代码

    利用了工厂模式将对象交给容器管理,你只需要在spring配置文件总配置相应的bean,以及设置相关的属性,让spring容器来生成类的实例对象以及管理对象。在spring容器启动的时候,spring会把你在配置文件中配置的bean都...

    java面试题

    spring使用AOP面向切面的思想进行事务管理的。 spring和Hibernate继承后,定义事务管理特性的时候查询为什么要定义为read-only? 答:因为添加、删除和更新都涉及到了数据库的修改,而查询并未涉及到数据库修改,...

    ormlitejar包

    通过对象类型的属性支持“外”对象,数据库中只存储外对象的id。 基本支持数据库事务。 自动生成创建、删除数据库表的SQL。 支持Spring配置。 支持不用注解配置表和字段。 支持Android SQLite数据库API的本地...

    JAVA上百实例源码以及开源项目

     用JAVA编写了一个小工具,用于检测当前显示器也就是显卡的显示模式,比如分辨率,色彩以及刷新频率等。 Java波浪文字制作方法及源代码 1个目标文件 摘要:Java源码,初学实例,波浪文字  Java波浪文字,一个利用...

    Java面试宝典2010版

    6、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序: 7、写一个Singleton出来。 8、递归算法题1 9、递归算法题2 10、排序都有哪几种方法?请列举。用JAVA实现一个...

    千方百计笔试题大全

    65、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别 17 66、HashMap和Hashtable的区别 17 67、说出ArrayList,Vector, LinkedList的存储性能和特性 17 68、java中有几...

    java面试宝典

    65、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别 17 66、HashMap和Hashtable的区别 17 67、说出ArrayList,Vector, LinkedList的存储性能和特性 17 68、java中有几...

    乐优商城.xmind

    自动纳入 Spring 的事务管理 使用默认配置,抛出异常之后,事务会自动回滚,数据不会插入到数据库。 setId(null) insert(brand) 新增中间表 mapper @Insert (#{cid},#{bid}) @Param 表示给参数命名,名称...

Global site tag (gtag.js) - Google Analytics