一、事务目的
事务在企业级应用程序中,用来确保数据的完整性和一致性。
二、事务的定义
事务是读写数据库的一系列程序动作,它们被作为一个独立的工作单元。这些程序动作要么全部完成,要么全部失败,不起作用。
三、事务的四个关键属性
原子性(atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成要么完全不起作用。
一致性(consistency):一旦事务完成,事务就被提交,数据和资源就处于一种满足业务规则的一致性中。
隔离性(isolation):多个事务可能同时处理相同的数据,因此,每个事务都应该与其他事务隔离开来,防止数据损坏。
持久性(durability):一旦事务完成,无论系统发生什么错误,结果都不因该受到影响。通常情况下,事务结果被写到持久化存储器中。
四、事务的传播行为
常用的传播行为:
REQUIRED:使用调用者事务;方法A和方法B均添加了事务,若果方法A调用的方法B,则方法B也使用方法A的事务。
REQUIRED_NEW:将调用者事务挂起,使用自己的事务。方法A和方法B均添加了事务,若果方法A调用的方法B,则方法B将方法A的事务挂起,并使用自己的事务。
五、事务的隔离级别
读未提交:事务B在更新数据库但还未提交的数据,如果此时事务A来读取数据,事务A可以读到事务B修改过的数据。
读已提交:事务B在更新数据库但还未提交的数据,那么事务A读不到事务B正在更新的值,只能看到已提交的数据。
可重复读:事务A读取了字段D的数据,然后进行业务逻辑处理,然后过段时间再读取字段D,在这个事务中,前后两次读取的数据应该一致(注:事务A没有修改字段D)。
可串行化:所有事务窜行执行。
六、事务的其他属性
readOnly:只读事务,数据库化做一些优化处理。
rollbackFor:发生xxxException.class异常回滚 。
norollbackFor: 发生xxxException.class异常不回滚。
timeout:制定事务回滚时间(事务在指定时间不完成,则强制回滚)。
七、spring 事务配置
- @Transactional 使用方式
<!--事务配置-->
<!-- 开启事物 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 事物注解驱动-->
<tx:annotation-driven/>
注意:<tx:annotation-driven/> 中的属性transaction-manager默认值为transactionManager,如果事务管理器的id不为transactionManager,则需要指定<tx:annotation-driven/>的transaction-manager属性,以保持一致,即
<!-- 开启事物 -->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 事物注解驱动-->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
通过添加@Transactional为方法添加事务;如果@Transactional添加在类上面,则为该类中的所有方法添加事务。
下面方法中,使用了“读已提交”的隔离级别、REQUIRED传播行为、发生任何异常(异常不被捕获)均回滚、事务必须在600毫秒内完成,超时则回滚。
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED,
noRollbackFor = Exception.class, timeout = 600)
public int insertData(UserEntity entity) {
//更新数据库操作1
//更新数据库操作2;
return 0;
}
- 基于xml配置事务
<!-- 开启事物 -->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置事务属性-->
<tx:advice id="txadvie" transaction-manager="dataSourceTransactionManager">
<tx:attributes>
<tx:method name="showUser" propagation="REQUIRED" isolation="READ_COMMITTED"/>
<tx:method name="updata" propagation="REQUIRES_NEW" isolation="READ_COMMITTED"/>
<!--代表处了上述方法外的方法-->
<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
<!--配置事务切入点,将事务切入点和事务属性关联起来-->
<aop:config>
<!--通过切入点指定需要添加事务的方法的位置-->
<aop:pointcut id="pointcut" expression="execution(* com.ssm.demo.service.*.*(..))"/>
<!--事务切入点和事务属性关联起来-->
<aop:advisor advice-ref="txadvie" pointcut-ref="pointcut"/>
</aop:config>
注:上面配置为包com.ssm.demo.service中所有的方法添加事务,其中方法:
showUser使用了REQUIRED传播行为和READ_COMMITTED隔离级别;
update使用了REQUIRED_NEW传播行为和READ_COMMITTED隔离级别;
剩下的其他方法使用了REQUIRED_NEW传播行为和DEFAULT隔离级别。