Spring声明式事务管理
为何要使用声明式事务管理功能呢?
案例:购物
在dao层定义了两个方法:1. 商品库存减1。2.用户账户减去商品价格
service层定义购物方法,调用dao层的两个方法。先执行2,在执行1.
如果方法1中出现了错误,这时候就会出现,用户账户已经扣除了金额但是商品库存却不变的情况。
因此我们就需呀使用声明式事务管理功能,将该方法定义为一个整体事务。
1. 使用步骤
- 在IOC容器中声明事务管理器,并开启基于注解的声明式事务管理功能。
<!-- 声明事物管理器 -->
<bean id="manager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 开启基于注解的声明式事物管理功能 -->
<tx:annotation-driven transaction-manager="manager"/>
- 在需要使用声明式事务管理功能的地方添加注解
@Transactional
,默认的事务传播机制为REQUIRED,即有一个错误整体回滚 - 如果一个事物中有多个独立的事务,我们不希望其中一个事物有异常导致全部回滚,这时候我们可以改变声明式事务的传播机制,
@Transactional(propagation = Propagation.REQUIRES_NEW)
,这样每个事务都是独立的 - 在阿里巴巴的规范手册中规定:需要在Transactional注解指定rollbackFor或者在方法中显式的rollback。 我们只需添加上
rollbackFor = Exception.class
或者rollbackFor = RuntimeException.class
即可。意为:当出现异常或运行时异常时进行回滚操作。
2. 声明式事务的隔离级别
mysql的四种隔离级别:读未提交
READ_UMCOMMITTED
,读已提交READ_COMMITTED
,可重复读REPEATABLE_READ
,可串行化SERIALIZABLE
默认的隔离级别为:可重复读REPEATABLE_READ
可以通过@Transactional(isolation = Isolation.READ_COMMITTED)
进行修改
3. 事务的超时回滚
@Transactional(timeout = 2)
设置如果超过2秒没有完成,则进行回滚
4. 事务的只读模式
如果事务中全都为读操作,可以设置为只读模式@Transactional(readOnly = true)
,方便数据库的底层优化。