基于注解实现事务管理
案例:买书案例,
书相关信息: bookId , bookName ,bookPrice
书库存信息: bookId,bookNum
账户信息: uid, price(余额)
如果进行如下操作:会导致,余额不足时,书的库存仍会减少。所以需要用到事务,来进行管理,当余额不足,无法完成交易时,进行回滚至交易前状态。
@Service("bookService")
public class BookServiceImpl implements BookService{
@Resource
private BookDao bookDao;
@Override
public int pruce(int bookid, int uid) {
// 获取书的单价
int price = bookDao.findPriceById(bookid);
// 更新书库存
bookDao.updateNumById(bookid);
// 更新账户余额
bookDao.updateAccount(price, uid);
return 0;
}
添加事务步骤:
--- 注:使用mysql 数据库时,首先要确保数据库表应使用 InnoDB 引擎 ,MyIsam 引擎是不支持事务的。
1、在配置文件中添加如下标签
<!-- 1.注册数据库连接信息 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="root"></property>
<property name="password" value="密码"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db_study">
</property>
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="initialPoolSize" value="20"></property>
<property name="maxPoolSize" value="25"></property>
</bean>
<!-- 2.配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 3.启用事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager" />
2.在相应方法上添加注解(@Transactional)---在遇到异常情况(注:异常需要自己捕捉)下,会自动回滚
@Service("bookService")
public class BookServiceImpl implements BookService{
@Resource
private BookDao bookDao;
@Transactional // 开启相应事务
@Override
public int pruce(int bookid, int uid) {
// 获取书的单价
int price = bookDao.findPriceById(bookid);
// 更新书库存
bookDao.updateNumById(bookid);
// 更新账户余额
bookDao.updateAccount(price, uid);
return 0;
}
3.事务相关
事务传播性--在遇到一个事务遇到另一个事务时,需要选择哪个事务。
设置 @Transactional相关属性 -- 属性如下
propagation : REQUIRED使用当前事务,不会开启新事务,REQUIRES_NEW将当前事务挂起,使用方法自己的事务。
isolation:设置事务隔离级别.
readOnly:开启只读事务
rollbackFor:遇到如下异常进行回滚
基于XML文件实现事务
<!--1. 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--2. 配置事务 -->
<tx:advice id="transaction" transaction-manager="transactionManager">
<tx:attributes>
<!-- 设置哪些方法需要配置事务,以及事务相关属性 -->
<tx:method name="*"/>
<tx:method name="get*" read-only="true"/>
<!-- ... -->
</tx:attributes>
</tx:advice>
<!--3.配置切点,把事务与方法联系起来 -->
<aop:config>
<aop:pointcut expression="execution(* com.yyl.*.*(..))" id="mypoint"/>
<aop:advisor advice-ref="transaction" pointcut-ref="mypoint"/>
</aop:config>