Spring 事务管理

记录下

spring 提供 声明式 事务管理,

发现较为方便的使用方式有两种,
1.xml 中配置 aspject 来实现
2.注解@Transactional

通用事务管理配置

<!-- 将事务与Hibernate关联 -->
    <bean id="transactionManager"
       class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref local="sessionFactory"/>
        </property>
    </bean>

通过 spring 配置bean transactionManager 这个事务管理器 与 hibernate 的关联起来,

然后下面开始说明不同的 方式
1.xml aop aspject 方式,通过指定 expression 到类,方法,来实现,比如下面的就指向到 com.lingganhezi.dao.BaseDao.*(..)) ,BaseDao下的所有方法 都由Aspject 切入,而tx:advice 则配置真正需要 事务的方法,以及事务的传播方式。

<aop:config>
        <aop:pointcut id="bussinessService"
            expression="execution(* com.lingganhezi.dao.BaseDao.*(..))" />
        <aop:advisor pointcut-ref="bussinessService" advice-ref="txAdvice" />
    </aop:config>

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" read-only="false" propagation="NOT_SUPPORTED" />
            <tx:method name="find*" read-only="false" propagation="NOT_SUPPORTED" />
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="delete*" propagation="REQUIRED" />
            <tx:method name="marge*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>

2.使用注解 @Transactional
这个就方便多了,直接注解在 由Spring 生产的类、或者方法中标识出它是需要执行 事务的,使用这种方式 方便快捷 可控性比较好,起码看代码看着舒服

@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DynamicFormService extends BaseService<DynamicForm> {

    @Transactional(rollbackFor = Exception.class)
    @Override
    public DynamicForm save(DynamicForm form) {
        DynamicForm saveForm = super.save(form);
        for (DynamicFormField field : form.getFields()) {
            field.setDynamicForm(saveForm);
        }
        saveForm.getFields().addAll(form.getFields());
        return super.save(saveForm);
    }
}

有几个注意点
1. @Transactional 注解的地方必须 是public,无论是注解在类还是方法 都需要public 出来。
2. 不能在方法内 把异常catch 住,不然无法 回滚,必须抛出
3. Spring 默认只会去处理 RuntimeException 的才会触发回滚事务,如果需要指定其他异常也 回滚数据 ,需要 rollbackFor = Exception.class
4. 一般注解在 Service 上 ,当然在 Controller上也行,不过试过 会出现问题
只有做了 requestMapping 的方法才生效(由Spring mvc 那边调过来的方法)
5.Transactional 有好几套传递策略

默认遇到throw new RuntimeException(“…”);会回滚
需要捕获的throw new Exception(“…”);不会回滚

// 指定回滚
@Transactional(rollbackFor=Exception.class)
public void methodName() {
// 不会回滚
throw new Exception(“…”);
}
//指定不回滚
@Transactional(noRollbackFor=Exception.class)
public ItimDaoImpl getItemDaoImpl() {
// 会回滚
throw new RuntimeException(“注释”);
}

// 如果有事务,那么加入事务,没有的话新建一个(不写的情况下)
@Transactional(propagation=Propagation.REQUIRED)
// 容器不为这个方法开启事务
@Transactional(propagation=Propagation.NOT_SUPPORTED)
// 不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
@Transactional(propagation=Propagation.REQUIRES_NEW)
// 必须在一个已有的事务中执行,否则抛出异常
@Transactional(propagation=Propagation.MANDATORY)
// 必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)
@Transactional(propagation=Propagation.NEVER)
// 如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.
@Transactional(propagation=Propagation.SUPPORTS)

@Transactional(propagation=Propagation.NESTED)
// readOnly=true只读,不能更新,删除
@Transactional (propagation = Propagation.REQUIRED,readOnly=true)
// 设置超时时间
@Transactional (propagation = Propagation.REQUIRED,timeout=30)
// 设置数据库隔离级别
@Transactional (propagation = Propagation.REQUIRED,isolation=Isolation.DEFAULT)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值