Spring事务管理

一、Spring事务 的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。

对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行:
   1. 获取连接 Connection con = DriverManager.getConnection()
   2.开启事务con.setAutoCommit(true/false);
   3.执行CRUD ( 增删改查 )
   4. 提交事务/回滚事务 con.commit() / con.rollback();
   5.关闭连接 conn.close();
使用Spring的事务管理功能后,我们可以不再写步骤 2 和 4 的代码,而是由Spirng 自动完成。 那么Spring是如何在我们书写的 CRUD 之前和之后开启事务和关闭事务的呢?解决这个问题,也就可以从整体上理解Spring的事务管理实现原理了。下面简单地介绍下,注解方式为例子
    配置文件开启注解驱动,在相关的类和方法上通过注解@ Transactional 标识。
    spring 在启动的时候会去解析生成相关的bean,这时候会查看拥有相关注解的类和方法,并且为这些类和方法生成代理,并根据@Transaction的相关参数进行相关配置注入,这样就在代理中为我们把相关的事务处理掉了(开启正常提交事务,异常回滚事务)。
    真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。
事务: 将若干的数据库操作作为一个整体控制,一起成功或一起失败,没有中间状态。
   原子性 :指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
   一致性 :指事务前后数据的完整性必须保持一致。
   隔离性 :指多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数据要相互隔离。
   持久性 :指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,即时数据库发生故障也不应该对其有任何影响。

- TransactionDefinition  事务定义信息(隔离、传播、超时、只读)
        脏读:一个事务读取了另一个事务改写但还未提交的数据,如果这些数据被回滚,则读到的数据是无效的。
        不可重复读:在同一事务中,多次读取同一数据返回的结果有所不同。
        幻读:一个事务读取了几行记录后,另一个事务插入一些记录,幻读就发生了。再后来的查询中,第一个事务就会发现有些原来没有的记录。
     
 二 事务隔离( isolation )级别 :(五种)
  •  默认   DEFAULT--使用后端数据库默认的隔离级别(Spring中的选择项)
  • 读未提交    READ_UNCOMMITED--允许你读取还未提交的改变了的数据。可能导致脏、幻、不可重复读
  • 读已提交    READ_COMMITTED--允许在并发事务已经提交后读取。可防止脏读,但幻读和不可重复读仍可发生
  •  可重复读   REPEATABLE_READ--对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏、不可重复读,但幻读仍可能发生
  •  可序列化  SERIALIZABLE--完全服从ACID的隔离级别,确保不发生脏、幻、不可重复读。这在所有的隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的
    总结:
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
大多数的数据库默认隔离级别为 Read Commited,比如 SqlServer、Oracle
少数数据库默认隔离级别为:Repeatable Read 比如: MySQL InnoDB,MySQL默认采用REPEATABLE_READ隔离级别;Oracle默认采用READ_COMMITTED隔离级别

 三 Spring 事务的传播属性
所谓spring事务的传播属性,就是定义在 有多个事务同时存在 的时候,spring应该如何处理这些事务的行为。这些属性在TransactionDefinition( 事务定义 )中定义,具体常量的解释见下表:
事务传播( propagation )行为:(七种)
           常量名称     常量解释
  •     required   --支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
  •     supports --支持当前事务,如果当前没有事务,就以非事务方式执行。
  •     mandatory  --支持当前事务,如果当前没有事务,就抛出异常。
  •     requires_new --新建事务,如果当前存在事务,把当前事务挂起。
  •     not_supported --以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  •     never--以非事务方式执行,如果当前存在事务,则抛出异常。
  •     nested --如果当前存在活动的事务,则在嵌套事务内执行。如果当前没有活动事务,则进行与required类似的操作。它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点,内部回滚不会对外部事务产生影响。只对DataSourceTransactionManager管理器有效

四 . Spring(如何 )配置事务的5种方式 :  http://blog.csdn.net/it_man/article/details/5074371
总结如下:   Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource、TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分。

    DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用 hibernate 进行数据访问时,DataSource实际为SessionFactory,TransactionManager的实现为HibernateTransactionManager。

五、Spring事务管理的四种方式(以银行转账为例)点击打开链接
 
六、总结
对于项目中需要使用到事务的地方,我建议开发者还是使用spring的TransactionCallback接口来实现事务,不要盲目使用spring事务注解,如果一定要使用注解,那么一定要对spring事务的传播机制和隔离级别有个详细的了解,否则很可能发生意想不到的效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值