Spring-06-声明式事务管理
十一、声明式事务
11.1 什么是事务?
- 事务就是把一系列的数据库操作看做一个最小的、不可分割的动作,要么都成功,要么都失败。用于确保数据的一致性和完整性
- 事务的ACID原则
- 原子性(Atomic)
- 一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
- 一致性(Consistency)
- 在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
- 例如:转账过程中,AB两个共1000元,那么不管事务怎么执行,两个人的钱的总和一定是1000不会变。除非有别的新事务发生
- 隔离性(Isolation)
- 数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
- 持久性(Durability)
- 事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。如果在系统故障前,事务没有提交,则回滚。不然,则保证更改
- 原子性(Atomic)
11.2 Spring的事务管理
- Spring在不同的事务管理API之上定义了一个抽象层,使得开发人员不必了解底层的事务管理API就可以使用Spring的事务管理机制。
- Spring支持编程式事务和声明式事务
编程式事务
- 最传统的事务管理方法
- 将涉及到事务提交和回滚的代码嵌入到业务执行过程中
- 每一个独立的业务都需要包含
声明式事务(最常用)
- 通过AOP的方式,将事务管理插入到业务执行过程中
- 简单,解耦,模块化
11.3 声明式事务
-
注意
-
要使用Spring进行事务管理,需要配置Spring的事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg ref="dataSource" /> </bean>
-
在配置文件中导入Spring中对事务的约束
xmlns:tx="http://www.springframework.org/schema/tx" http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
-
-
开启Spring事务管理
<!--开启Spring事务管理--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
-
配置事务通知,也就是说什么样的操作需要事务
<!--配置事务通知--> <tx:advice id="interceptor" transaction-manager="transactionManager"> <tx:attributes> <!--配置方法要使用的事务隔离等级和传播特性,一般使用默认的即可--> <tx:method name="*" propagation="REQUIRED" isolation="DEFAULT"/> </tx:attributes> </tx:advice>
-
配置AOP
<aop:config> <aop:pointcut id="transaction" expression="execution(* com.pbx.mapper.*.*(..))"/> <aop:advisor advice-ref="interceptor" pointcut-ref="transaction"/> </aop:config>
-
测试
-
test是在一个业务实现类中的具体业务处理
public void test() { UserMapper mapper = getSqlSession().getMapper(UserMapper.class); mapper.addUser(new User(5, "吴尊", "1235")); mapper.deleteUser(12); for (User user : mapper.getAllUser()) { System.out.println(user); } }
-
测试类,因为没有12条数据,所以删除时会报错
@Test public void test4() { UserMapperImpl2 bean = context.getBean("userMapperImpl2", UserMapperImpl2.class); bean.test(); }
-
执行完之后,可以看到id为5的数据并没有添加到数据库中
-