spring 对事务的支持

非注解事务

<!-- 事务管理器-->
    <bean id="txManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="c3p0DataSource" />
    </bean> 

    bean id="c3p0DataSource"
        class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <!-- 不注册jmx -->
        <!-- <constructor-arg type="boolean"  value="false" /> -->
        <property name="driverClass" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/wjh"/>
        <property name="user" value="root" />
        <property name="password" value="root" />

    </bean>

c3P0不能使用最新版本的,非注解的事务要使用老版本,新版本有bug,会报错,我使用0.8.4.5的,使用0.9.1.1会报空指针异常

业务层代码

@Resource(name="txManager")
    private DataSourceTransactionManager tm;

    public @ResponseBody String insert() {
        TransactionTemplate tran = 
                new TransactionTemplate(tm);
        return tran.execute(new TransactionCallback<String>() {
            @Override
            public String doInTransaction(TransactionStatus status) {
                User user = new User();
                user.setEmail("223@qq.com");
                user.setPassword("123");
                user.setNickname("weck");
                UserInfo info = new UserInfo();
                info.setUser(user);
                info.setAge(16);
                info.setSex("男");
                userMapper.saveUser(user);
                userMapper.saveUserInfo(info);
                return "ok";
            }
        });
    }

如果不想有返回值可以这么写

TransactionTemplate tran = 
            new TransactionTemplate(tm);
    tran.execute(new TransactionCallbackWithoutResult() {
        @Override
        public void doInTransactionWithoutResult(TransactionStatus status) {
            User user = new User();
            user.setEmail("223@qq.com");
            user.setPassword("123");
            user.setNickname("weck");
            UserInfo info = new UserInfo();
            info.setUser(user);
            info.setAge(16);
            info.setSex("男");
            userMapper.saveUser(user);
            userMapper.saveUserInfo(info);
            //return "ok";
        }
    });

在非注解事务中,我们可以设置事务保存点

    TransactionTemplate tran = 
            new TransactionTemplate(tm);
        tran.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus tran) {
                Object obj = tran.createSavepoint(); //创建事务保存点
                tran.releaseSavepoint(obj); //释放保存点
                tran.rollbackToSavepoint(obj); //回滚到保存点
            }
        });

注解事务

需要aopalliance-1.0.jar

在spring-mvc.xml文件中

    <!-- 事务管理器 -->
    <bean id="txManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="c3p0DataSource" />
    </bean>

    <!-- 事务注解驱动,标注@Transactional的类和方法将具有事务性 -->
    <tx:annotation-driven transaction-manager="txManager" />

注意:transactionManager是事务默认id,transaction-manager=”transactionManager”这个属性省略不写

    <!-- 事务管理器-->
    <bean id=""transactionManager""
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean> 

    <!-- 事务注解驱动,标注@Transactional的类和方法将具有事务性 -->
    <tx:annotation-driven />

处理业务代码

@RequestMapping(value="/insert",produces="text/html;charset=utf-8")
    @Transactional
    public @ResponseBody String insert(){
        User user = new User();
        user.setEmail("223@qq.com");
        user.setPassword("123");
        user.setNickname("weck");
        UserInfo info = new UserInfo();
        info.setUser(user);
        info.setAge(16);
        info.setSex("男");
        userMapper.saveUser(user);
        userMapper.saveUserInfo(info);
        return "ok";
    }

只要加了@Transactional,会自动执行事务,一但在一个中间某处业务出错,不会被提交,数据库便不会插入任何信息,声明式事务管理是利用Spring AOP实现的,注解的使用简单,对代码没有侵入性,逻辑更清晰

@Transactional标记有以下属性,在使用时可以根据需要做特殊设定

  • propagation 设置事务传播
  • isolation 设置事务隔离级别
  • timeout 设置超时时间
  • readOnly 设置为只读
  • rollbackFor 或 rollbackForClassName 设置哪些异常回滚
  • noRollbackFor 或 noRollbackForClassName 设置哪些异常不回滚

@Transactional 注解属性默认设置如下:

  • 事务传播设置是 Propagation.REQUIRED
  • 事务隔离级别是 Isolation.DEFAULT
  • 事务可读写
  • 事务超时默认依赖事务系统的,或者事务超时没有被支持
  • 任何RuntimeException 将触发事务回滚,但是任何Checked Exception 将不触发事务回滚

在xml中实现声明式事务

<tx:advice id="txAdvice"  transaction-manager="txManager" >
        <tx:attributes>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="delete*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>

    <aop:config proxy-target-class="true">
        <aop:advisor advice-ref="txAdvice" pointcut="within(spring.controller..*)" />
    </aop:config>

事务的回滚异常

异常分类

  1. 检查异常(编译异常)
  2. 运行时异常

运行时异常直接回退,检查异常需要指定回退

这里写图片描述

对于Checked Exception,需要手动指定异常类型,才能实现事务回滚

使用注解声明式事务,如下方式指定异常:

@Transactional(rollbackFor=ClassNotFoundException.class)

使用xml配置声明式事务如下:

<tx:method name="update*" propagation="REQUIRED" 
            rollback-for="java.lang.ClassNotFoundException"/>

这里写图片描述

这里写图片描述

<tx:method name="find*" read-only="true" isolation="READ_COMMITTED" />

设置隔离级别为读取提交的数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值