Spring 中的事务及管理

1.什么是事务

  事务必须服从ACID原则,ACID指的是原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)。通俗理解,事务其实就是一系列指令的集合。

2.为什么要用事务

  我们经常会遇到这样的问题,在同一时刻不同的业务逻辑对一个数据库表数据进行操作,这时可能就导致冲突。经常举的一个例就是银行取钱.两个人同时读取余额,A读出为1000,B读出为1000,A读出后又存了100,B读出后取了200,最后结果变为了800.这就造成了丢失更新

3.事务的分类(按不同的类型分)

  3.1实现的角度分为:JDBC事务、JTA(Java Transaction API)事务、容器事务

  JDBC事务:JDBC的一切行为包括事务是基于一个Connection的,在JDBC中是通过Connection对象进行事务管理,常见的就是方法有设置事务是否自动提交 setAutoCommit,事务开启beginTransaction,事务提交commit,事务回滚rollback
  优点:可将多个SQL放在同一个事务中,保证ACID特性;API较简单,可实现最基本的事务操作,性能相对较好
  缺点:一个JDBC事务不能跨越多个数据库,即如果涉及到多个数据库的操作或分布式场景,JDBC就不能在适用了


  JTA事务:(Java Transaction API缩写),java事务API,是一个java企业版的应用程序接口,解决了JDBC的缺陷,即支持分布式事务,可处理跨越多个数据库的事务,是分布式事务的一种解决方案
  优点:可处理跨越多个数据库的事务
  缺点:实现复杂,需要有一个实现 javax.sql.XADataSource 、 javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC 驱动程序


      3.2事务管理的角度分为:编程式事务、声明式事务

  编程式事务:就是直接在代码里手动开启事务,手动提交,手动回滚。优点就是可以灵活控制,缺点就是太麻烦了,太多重复的代码了。
  声明式事务:就是使用Spring AOP配置事务,这种方式大大的简化了编码。需要注意的是切入点表达式一定要写正确。
  注解事务:直接在Service层的方法上面加上@Transactional注解,个人比较喜欢用这种方式。

4.事务的特性

  4.1传播性

  4.2 回滚规则

  4.3事务只读属性

  4.4事务超时

  4.5事务隔离级别

5.并发事务导致的问题

  参考文章:http://blog.csdn.net/gloomy_114/article/details/62048335

6.为什么事务能回滚(怎么知道是提交还是回滚)

  是因为使用了二次提交协议,即如果你先执行第一条语句,执行的结果先预提交到数据库,预提交到数据库了,数据库会执行这条语句,然后返回一个执行的结果,这个结果假如我们用布尔值表示的话,成功就是true,失败就是false.然后把执行的结果放入一个(假设是List)对象里面去,接下来再执行第二条语句,执行完第二条语句之后(也是预处理,数据库不会真正实现数据的提交,只是说这条语句送到数据库里面,它模拟下执行,给你返回个执行的结果),假如这两条语句的执行结果在List里面都是true的话,那么这个事务就认为语句是成功的,这时候全局事务就会提交。二次提交协议,数据库在第一次提交这个语句时,只会做预处理,不会发生真正的数据改变,当我们在全局事务提交的时候,这时候发生了第二次提交,那么第二次提交的时候才会真正的发生数据的改动。 如果说在执行这两条语句中,有一个出错了,那么List集合里就有个元素为false,那么全局事务就认为你这个事务是失败的,它就会进行回滚,回滚的时候,哪怕你的第二条语句在第一次提交的时候是成功的,它在第二次提交的时候也会回滚,那么第一次的更改也会恢复到之前的状态,这就是二次提交协议

7.事务管理

  用spring的事务管理器实现

<!--事务管理器  ,对mybatis操作数据库事务控制,spring使用jdbc的事务控制类-->
        <bean  id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <!-- 数据源,在另一个配置文件applicationContext-dao.xml中配置了 -->
            <property name="dataSource" ref="dataSource" /> 
        </bean>     

        <!-- 通知 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <!-- 传播性 -->
                <tx:method name="save*" propagation="REQUIRED"/>
                <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>           
            </tx:attributes>
        </tx:advice>

        <aop:config>
            <aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.itcast.ssm.service.impl.*.*(..))"/>
        </aop:config>

猜你喜欢

转载自blog.csdn.net/wrs120/article/details/79598972