spring 对事务的支持

来源:互联网 发布:python 函数定义输出 编辑:程序博客网 时间:2024/06/06 08:54

非注解事务

<!-- 事务管理器-->    <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" />

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

原创粉丝点击