spring事物注解配置
第一步:在配置文件中映入< tx: >命名空间(下划线标志)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
---------------------------------------------------
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
http://www.springframework.org/schema/tx
----------------------------------------
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
-----------------------------------------------------------
第二步:在配置文件中配置事物管理器,mybatis和hibernate有所不同
mybatis:
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据库的连接池 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置基于注解的声明式事物 ,默认使用注解管理事务行为-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
Hibernate:
<!-- Hibernate事务管理器配置 -->
<bean id="defaultTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 使用annotation定义事务 -->
<tx:annotation-driven transaction-manager="defaultTransactionManager" proxy-target-class="true" />
第三步:在接口或类的声明处 ,写一个@Transactional. 要是只在接口上写, 接口的实现类就会继承下来、接口的实现类的具体方法,可以覆盖类声明处的设置
eg:
public class SeckillServiceImpl implements SeckillService{
//为减少篇幅,部分代码省略
@Transactional
public SeckillExecution executeSeckill(long seckillId, long userPhone,
String md5) throws SeckillException, RepeatKillException,
SeckillCloseException {
if(md5==null||md5.equals(getMD5(seckillId))){
throw new SeckillException("seckill data rewrite");
}
//执行秒杀逻辑,记录购买行为
Date nowTime=new Date();
try {
//减库存
int updateCount=seckillDao.reduceNumber(seckillId, nowTime);
if(updateCount<=0){
//没有更新到记录,秒杀结束
throw new SeckillCloseException("seckill is closed");
}else{
//记录购买行为
int insertCount=successKilledDao.insertSuccessKilled(seckillId, userPhone);
if(insertCount<=0){
//重复秒杀
throw new RepeatKillException("seckill repeated");
}else{
//秒杀成功
SuccessKilled successKilled=successKilledDao.queryByIdWithSeckill(seckillId, userPhone);
return new SeckillExecution(seckillId, SeckillStatEnum.SUCCESS,successKilled);
}
}
}catch (SeckillCloseException e1) {
throw e1;
}catch (RepeatKillException e2) {
throw e2;
}catch (Exception e) {
logger.error(e.getMessage(),e);
//所有编译异常 转化为运行期异常
throw new SeckillException("seckill inner error");
}
}
}
以上实例中,方法executeSeckill前加了@Transactional,已经有了事物管理,会自动的事务提交,回滚等操作。
注意的几点:
1,不是所有的方法都需要事务,如果只有一条修改操作,或者只执行读操作,或者写入的n条操作之间不存在逻辑关系的时候,是不需要事务的。
2,应该尽可能的保证事务的执行效率,在事务方法中,尽可能的排除其他的功能代码,比如不要穿插着网络操作等
发表人:梦想的边缘