Spring 事务异常处理

来源:互联网 发布:java字符串前后去空格 编辑:程序博客网 时间:2024/05/18 03:33

一、引言

JavaWeb 开发的经典三层架构:
① DAO 层,基本是对数据库数据的增删改查,
② Service 层,一般调用多个 DAO 的方法

三层架构在 Spring 事务处理中就显得分层是十分重要了,一旦执行到中间,出现意外就可以全部数据修改回来,只有一层DAO甚至直接Servlet,就会局部修改数据了。

二、代码
(1)代码结构
这里写图片描述
(2)代码与解释
①JavaBean.java 实体类

package jdbc;public class JavaBean {    public JavaBean() {        super();        // TODO Auto-generated constructor stub    }    @Override    public String toString() {        return "JavaBean [id=" + id + ", userName=" + userName + ", password=" + password + "]";    }    public JavaBean(Integer id, String userName, String password) {        super();        this.id = id;        this.userName = userName;        this.password = password;    }    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getUserName() {        return userName;    }    public void setUserName(String userName) {        this.userName = userName;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    private Integer id;    private String userName;    private String password;}

②DAOinterface.java DAO 接口

package jdbc;public interface DAOinterface {    public void add();}

③DAOimplements.java DAO 接口实现类

package jdbc;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class DAOimplements extends JdbcDaoSupport implements DAOinterface{    @Override    public void add() {        // TODO Auto-generated method stub        String sql="INSERT INTO jikeuser(userName,password) VALUES('tx',22)";        super.getJdbcTemplate().update(sql);    }}

④ServiceInterface.java 事务接口

package jdbc;public interface ServiceInterface {    void  doubleAdd();}

⑤ServiceInterface 事务接口实现类

package jdbc;import org.springframework.transaction.annotation.Transactional;import org.springframework.transaction.support.TransactionTemplate;@Transactional() //查看数据新增的数据的id,可知会把下下面插入的行的删除public class ServiceImplements implements ServiceInterface {    public void setDao(DAOinterface dao) {        this.dao = dao;    }    public void setTt(TransactionTemplate tt) {        this.tt = tt;    }    private DAOinterface dao;    private TransactionTemplate tt;    @Override    public void doubleAdd() {        // TODO Auto-generated method stub        dao.add();        int i=10/0; //制造断电现象        dao.add();    }}

⑥ Test.java 测试类

package jdbc;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.transaction.annotation.Transactional;public class Test {    @org.junit.Test    public void add() {        //正常加入一条数据到数据库中。        System.out.println("测试增加...");        ApplicationContext ac = new ClassPathXmlApplicationContext("jdbc/jdbcContext.xml");        DAOinterface cun = (DAOinterface) ac.getBean("userDao");        cun.add();    }    @org.junit.Test    public void doubleAdd() {        //会发现数据的数据没有什么变化,是由于 jdbc/ServiceImplements.java 中的 @Transactional() 的作用,        //若去掉这个注解美酒会发现数据多了一条数据        System.out.println("正在测试双倍增加...");        ApplicationContext ac = new ClassPathXmlApplicationContext("jdbc/jdbcContext.xml");        jdbc.ServiceInterface cun = (jdbc.ServiceInterface) ac.getBean("accountService");        cun.doubleAdd();    }}

⑦ db.properties 数据库配置文件

jdbc.jdbcUrl=jdbc:mysql:///bookjdbc.driverClass=com.mysql.jdbc.Driverjdbc.user=rootjdbc.password=123

⑧jdbcContext.xml Spring配置文件

<?xml version="1.0" encoding="UTF-8"?><beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">    <!-- 指定spring读取db.properties配置 -->    <context:property-placeholder location="classpath:jdbc/db.properties" />    <!-- 1.将连接池放入spring容器 -->    <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>        <property name="driverClass" value="${jdbc.driverClass}"></property>        <property name="user" value="${jdbc.user}"></property>        <property name="password" value="${jdbc.password}"></property>    </bean>    <!-- 2.将JDBCTemplate放入spring容器 -->    <bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">        <property name="dataSource" ref="dataSource"></property>    </bean>    <!-- 3.将UserDao放入spring容器 -->    <bean name="userDao" class="jdbc.DAOimplements">        <property name="dataSource" ref="dataSource"></property>    </bean>    <!-- 开启使用注解管理aop事务 -->    <tx:annotation-driven />    <!-- 事务核心管理器,封装了所有事务操作. 依赖于连接池 -->    <bean name="transactionManager"        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">        <property name="dataSource" ref="dataSource"></property>    </bean>    <!-- 事务模板对象 -->    <bean name="transactionTemplate"        class="org.springframework.transaction.support.TransactionTemplate">        <property name="transactionManager" ref="transactionManager"></property>    </bean>    <!-- 3.Service -->    <bean name="accountService" class="jdbc.ServiceImplements">        <property name="dao" ref="userDao"></property>        <property name="tt" ref="transactionTemplate"></property>    </bean></beans>

三、功能演示

①演示前数据库表信息
这里写图片描述

②执行第一个正常增加一条信息的 test,正常加入一条信息纪录
数据库表的数据如下:
这里写图片描述
console 输出:
这里写图片描述
③执行第二个增加两条数据的而中间”断电”的 test:发送了异常
数据库表的数据如下:似乎没有发送变化
这里写图片描述
console输出
这里写图片描述
④再执行第一个正常增加一条信息的 test:会发现数据id中间隔了13,是之前增加进去,被自动删除的
数据库表的数据如下
这里写图片描述
console 输出
这里写图片描述

原创粉丝点击