【Spring】Spring之事务处理

编程式事务

    /**
     * 1.   根据DataSource去创建事务管理器
     *      构造方法 , 参数1. DataSource
     */
    DataSourceTransactionManager txManager = new DataSourceTransactionManager(getDataSource());
    /**
     * 2.   创建事务模版对象, 并将事务管理器传递给模版
     */
    TransactionTemplate ttlate = new TransactionTemplate(txManager);

    /**
     * 3.   通过事务模版 , 执行事务, 并指定事务的回调函数
     */
    Boolean flag = ttlate.execute(new TransactionCallback<Boolean>() {

        /**
         *  我们要处理的JDBC操作, 可以放到这个方法中,  在这个方法里的所有JDBC操作, 将视为一个事务
         *
         *  这个方法, 如何认定事务是否应该提交 :
         *
         *      当方法中出现异常, 则表示事务执行失败 ,
         *      如果异常进行了处理, 则事务执行成功!
         */
        @Override
        public Boolean doInTransaction(TransactionStatus status) {
            try{

                getJdbcTemplate().update("update book set bookname=? where bookid=?", "西游记",10002);
                    if(1==2){
                        throw new RuntimeException("停电了, 哈哈哈");
                    }
                getJdbcTemplate().update("update book set bookname=? where bookid=?", "红楼梦",10003);
                return true;
            }catch(Exception e){
                e.printStackTrace();
                //处理了异常 , 没事了
                //加入回滚标记 ( 本次事务不提交  )
                status.setRollbackOnly();
                return false;

            }
        }
    });
    System.out.println("事务执行的结果:"+flag);

声明式事务

相较于编程式的事务 ,有利有弊 !

优点:

是一种aop的编程思想, 给一段代码添加事务, 无需修改原代码

缺点:

因为采用了注解, 注解的最小范围只能给类的成员 , 也就是说, 声明时的事务 ,最小的处理范围是一个方法 !

使用步骤:

1.  向容器中添加事务的管理对象
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <constructor-arg index="0" ref="dataSource"></constructor-arg>
</bean>

2.  开启事务的扫描 , 指定事务管理器

<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>

3.  在具体要被执行事务的方法上, 添加注解@Transaction即可

@Transactional注解的属性

@Transactional注解标记有以下属性,在使用时
可以根据需要做特殊设定。
propagation: 设置事务传播
isolation : 设置事务隔离级别
readOnly : 设置为只读,还是可读写
rollbackFor : 设置遇到哪些异常必须回滚
noRollbackFor : 设置遇到哪些异常不回滚

看一个Demo:

User类:

package cn.wxg.bean;

public class User {

    private int id;
    private String name;
    private String password;
    public User() {
        super();
    }
    public int getId() {
        return id;
    }
    public User(int id, String name, String password) {
        super();
        this.id = id;
        this.name = name;
        this.password = password;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", password=" + password + "]";
    }

}

User.java

Dao类:

package cn.wxg.dao;

import java.util.List;

import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import cn.wxg.bean.User;

public class UserDao extends JdbcDaoSupport {

    @Transactional
    public void test2(List<User> user){
        String sql1="update test_user set password=? where name=?";
        String sql2="update test_user set password=? where name=?";

        getJdbcTemplate().update(sql1, user.get(0).getPassword(),user.get(0).getName());
        getJdbcTemplate().update(sql2, user.get(1).getPassword(),user.get(1).getName());
    }

    public boolean updateUser(List<User> user){
        String sql1="update test_user set password=? where name=?";
        String sql2="update test_user set password=? where name=?";

        //声明事务管理组件
        DataSourceTransactionManager dstt = new
                DataSourceTransactionManager(getDataSource());
        //声明事务组件
        TransactionTemplate tt = new
                TransactionTemplate(dstt);
        //执行事务
        Boolean res = tt.execute(new TransactionCallback<Boolean>(){

            @Override
            public Boolean doInTransaction(TransactionStatus status){
                try{
                    getJdbcTemplate().update(sql1, user.get(0).getPassword(),user.get(0).getName());
                    getJdbcTemplate().update(sql2, user.get(1).getPassword(),user.get(1).getName());
                    return true;
                }catch(Exception e){
                    status.setRollbackOnly();//回滚
                }
                return false;
            }
        });
        return res;
    }
}

UserDao

XML文件:

<?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:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">

     <bean id="database" class="org.apache.commons.dbcp.BasicDataSource">
        <!-- 驱动地址 -->
        <property name="driverClassName" value="oracle.jdbc.OracleDriver"></property>
        <!-- 数据库的连接地址 -->
        <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"></property>
        <!-- 数据库的帐号 -->
        <property name="username" value="system"></property>
        <!--  数据库的密码 -->
        <property name="password" value="517839"></property>
     </bean>

    <bean id="userDao" class="cn.wxg.dao.UserDao">
    <!--
        在调用set方法进行赋值,
        Spring容器是通过反射技术 ,根据我们传递的name参数 , 得到对应的set方法名称, 将其调用
     -->
        <property name="dataSource" ref="database"></property>
    </bean>

    <!--配置DataSourceTransactionManager,事务管理着对象|-->
    <bean id="txManage" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <constructor-arg index="0" ref="database"></constructor-arg>
    </bean>

   <!--开启事务扫描-->
     <tx:annotation-driven transaction-manager="txManage" proxy-target-class="true"/>
    <!--文件扫描-->
    <context:component-scan base-package="cn"></context:component-scan>

</beans>

applicationContext.xml

测试类:

package cn.wxg.text;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.wxg.bean.User;
import cn.wxg.dao.UserDao;

public class UserDaoTest {

    @Test
    public void testName1() throws Exception {
        //加载配置文件
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = ac.getBean("userDao", UserDao.class);
        User user1=new User(1001,"jame","987654321");
        User user2=new User(1002,"locy","987654321");
        List<User> users=new ArrayList<User>();
        users.add(user1);
        users.add(user2);
//        System.out.println(userDao.updateUser(users));
        userDao.test2(users);

    }
}

UserDaoTest.java

时间: 2024-08-03 05:32:57

【Spring】Spring之事务处理的相关文章

基于Spring + Spring MVC + Mybatis + shiro 高性能web构建

一直想写这篇文章,前段时间 痴迷于JavaScript.NodeJs.AngularJS,做了大量的研究,对前后端交互有了更深层次的认识. 今天抽个时间写这篇文章,我有预感,这将是一篇很详细的文章,详细的配置,详细的注释,看起来应该很容易懂. 用最合适的技术去实现,并不断追求最佳实践.这就是架构之道. 希望这篇文章能给你们带来一些帮助,同时希望你们可以为这个项目贡献你的想法. 源码地址:https://github.com/starzou/quick4j 点击打开 看我们的项目结构: 是一个典型

SpringMVC学习系列(12) 完结篇 之 基于Hibernate+Spring+Spring MVC+Bootstrap的管理系统实现

到这里已经写到第12篇了,前11篇基本上把Spring MVC主要的内容都讲了,现在就直接上一个项目吧,希望能对有需要的朋友有一些帮助. 一.首先看一下项目结构: InfrastructureProjects:是抽取出的基础项目,主要封装了一些通用的操作. SpringMVC3Demo:就是管理系统所在的项目. WeiXinAPI:是之前做微信管理平台测试时封装一些操作,如果不需要把该项目移除即可. 注:项目的前端UI框架用的是国外的一个基于Bootstrap框架的开发的Demo,如不需要替换为

Maven+Hibernate+Spring+Spring MVC开发新闻发布系统

使用Maven+Hibernate+Spring+Spring MVC开发新闻发布系统 课程学习地址:http://www.xuetuwuyou.com/course/163 课程出自学途无忧网:http://www.xuetuwuyou.com 课程介绍 一.课程用到的软件: 1.jdk 1.8 2.eclipse neon 3.tomcat 8 4.jetty 5.MySQL  6.navicat 9+ 二.课程涉及到的技术点 1.Maven基础 2.Maven高级 3.Hibernate

Spring+Spring MVC+MyBatis实现SSM框架整合详细教程【转】

关于Spring+SpringMVC+Mybatis 整合,见还有不少初学者一头雾水,于是写篇教程,初学者按部就班的来一次,可能就会少走不少弯路了. 一:框架介绍(啰嗦两句,可自行度娘) 1.1:Spring Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来.它是为了解决企业应用开发的复杂性而创建的

[转]基于Spring + Spring MVC + Mybatis 高性能web构建

http://blog.csdn.net/zoutongyuan/article/details/41379851/ 一直想写这篇文章,前段时间 痴迷于JavaScript.NodeJs.AngularJs,做了大量的研究,对前后端交互有了更深层次的认识. 今天抽个时间写这篇文章,我有预感,这将是一篇很详细的文章,详细的配置,详细的注释,看起来应该很容易懂. 用最合适的技术去实现,并不断追求最佳实践.这就是架构之道. 希望这篇文章能给你们带来一些帮助,同时希望你们可以为这个项目贡献你的想法. 源

基于Spring + Spring MVC + Mybatis 高性能web构建

一直想写这篇文章,前段时间 痴迷于JavaScript.NodeJs.AngularJs,做了大量的研究,对前后端交互有了更深层次的认识. 今天抽个时间写这篇文章,我有预感,这将是一篇很详细的文章,详细的配置,详细的注释,看起来应该很容易懂. 用最合适的技术去实现,并不断追求最佳实践.这就是架构之道. 希望这篇文章能给你们带来一些帮助,同时希望你们可以为这个项目贡献你的想法. 源码地址:https://github.com/starzou/quick4j 点击打开 看我们的项目结构: 是一个典型

Spring+Spring MVC+Hibernate环境搭配

Spring+Spring MVC+Hibernate简称"SSH".Spring容器是Spring的核心,该 容器负责管理spring中的java组件.Spring的核心机制:依赖注入.Hibernate是一个不错的ORM(关系对象映射)框架.Spring+Spring MVC+Hibernate环境搭配步骤: 1.搭建Spring+Hibernate环境(跟ssh搭建步骤一致) (1)加入Spring+Hibernate的架包. 2.搭建SpringMVC环境( 1)添加Sprin

spring spring data jpa save操作事务

整合spring spring data jpa的时候,在save方法上加了@Transactional注解. 此时调用springdatajpa save方法并不会真的把数据提交给数据库,而是缓存起来. 提交事务后数据插入进数据库,要想在事务提交之前避免缓存插入数据库需要在执行完save操作调用flush方法或者直接执行saveAndFlush方法即可

maven/eclipse搭建ssm(spring+spring mvc+mybatis)

maven/eclipse搭建ssm(spring+spring mvc+mybatis) 前言 本文旨在利用maven搭建ssm环境,而关于maven的具体内容,大家可以去阅读<Maven 实战>.其实园内这方面文章已有不少,那么为什么我还要重复造轮子呢?我只是想记录自己的实践过程罢了,附带着给别人以参考.对于别人的博文,看了固然好,要是能付之实践,那就更好了! maven安装 安装过程挺简单的,去apache下载apache-maven的zip包,解压到一个目录下,如下图 接下来配置win

[Java][Spring]Spring事务不起作用 问题汇总

[Java][Spring]Spring事务不起作用 问题汇总 http://blog.csdn.net/szwangdf/article/details/41516239