1、理解
理解事务之前,先举个例子:取钱。
你去ATM取1000元,大体分为两步:首先输入密码、金额,银行卡扣去1000元,然后ATM出1000.这两个步骤必须是要么都执行要么都不执行。如果银行卡扣除1000但是ATM出钱失败,你将损失1000;如果银行卡扣钱失败但是ATM却出了1000,那么银行将损失1000.所以,如果一个步骤成功另外一个步骤失败对双方都不是好事,如果不管哪一个步骤失败了以后,整个取钱过程都能回滚,也就是完全取消所有操作的话,这对双方都是极好的
事务就是解决类似问题的。事务是一系列的动作,他们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的话,那么事务就会回滚到最开始的状态,仿佛什么都没发生过一样
在企业级应用程序开发中,事务管理是必不可少的技术,用来确保数据的完整性和一致性。
事务有四个特性:ACID
. 原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用
. 一致姓(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中数据不应该被破坏
. 隔离性(Isolation):可能有许多事务会同时处理形同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏
。 持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该收到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久存储器中。
2、Spring事务管理
1)Spring框架提供全面的事务支持,它提供一致事务管理方式:
- 提供简单易用的编程式事务管理API
- 支持声明式事务管理
2)编程式事务
使用编程式事务时,Spring提供以下两种事务管理的API
- TransactionTemplate
- PlatformTransactionManager
注:如果采用编程式事务管理,推荐使用TransactionTemplate
TransactionTemplate与Spring中JdbcTemplate等模板类风格相似,它也使用回调机制,将事务代码和业务代码分离,便于开发者将精力集中在具体的业务编程上
3)声明式事务
Spring的声明式事务管理是通过Spring AOP实现的,使用时不需要修改原有的业务代码,只需要通过简单配置就可以追加事务控制功能,大多数Spring用户选择声明式事务管理,对程序代码影响最小,也最符合非侵入的理念
3、注解实现声明式事务
1)在配置文件中声明事务管理组件,开启事务注解扫描
<!--声明事务管理组件-->
<bean id="" class="">
<property name="dataSource" ref=""/>
</bean>
<!--开启事务注解扫描-->
<tx:annotation-driven transaction-manager=""/>
transaction-manager指定事务管理器,需要根据数据库访问技术的不同选择不同的实现,例如JDBC,MyBatis技术选择DataSourceTransactionManager而Hibernate技术则选择HibernateTransactionManager
2)使用@Transactional注解
* @Transactional注解标记可以用在类定义前和方法定义前,方法上的事务设置将优于类级别注解的事务设置
* @Transactional注解标记有以下属性,在使用时可以根据需要指定
- propagation:事务传播,默认值是propagation_required
- isolation:事务隔离,默认值是isolation_default
- readOnly:只读/读写,默认值是可读写
- rollbackFor:遇到哪些异常回滚
- noRollbackFor:遇到哪些异常不回滚
4、XML配置实现声明式事务
在配置文件中声明事务管理组件,配置事务作用的范围及类型
<!--声明事务管理组件-->
<bean id="" class="">
<property name="dataSource" ref=""/>
</bean>
<!--XML配置声明事务范围及类型-->
<tx:advice id="" transaction-manager="">
<tx:attributes>
<tx:method name="" propagation=""/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor advice-ref="" pointcut=""/>
</aop:config>
5、事务回滚
默认情况下RuntimeException异常将触发事务回滚,任何CheckedException将不触发事务回滚,常见RuntimeException和CheckedException如下:
RuntimeException:
-NullPointerException
-ClassCastException
-NumberFormatException
-IndexOutOfBoundsException
CheckedException:
-ClassNotFoundException
-IOException
-NoSuchMethodException
-NoSuchFieldException
-- 使用注解实现声明式事务,按如下操作指定异常:
@Transactional(rollbackFor=ClassNotFoundException.class)
-- 使用XML配置实现声明式事务时,按如下操作指定异常:
<tx:method name="" rollback-for="java.lang.ClassNotFoundException"/>
6、事务传播
是指一个方法调用了另一个带有事务控制的方法,就需要指定事务传播的处理方案
7、事务隔离
在数据库操作过程中,如果两个事务并发执行,那么彼此之间的数据会发生影响,为了避免这种并发冲突,需要将两个书屋隔离开。