zoukankan      html  css  js  c++  java
  • 【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.  在具体要被执行事务的方法上, 添加注解@Transactional即可
    @Transactional也可以添加到类上,表示对该类的所有方法使用事务

    @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
  • 相关阅读:
    HDU 3709 数位dp
    Educational Codeforces Round 64 (Rated for Div. 2)-C. Match Points
    POJ 1845乘法逆元+约数和
    POJ3696 欧拉定理
    NC24953 树形dp(最小支配集)
    Codeforces 1173 C 思维+模拟
    Codeforces 1324F 树形dp+换根
    codeforces-1285D(字典树)
    面向纯小白的CLion(C++)基于Windows的安装配置教程
    HDU-2825Wireless Password(AC自动机+状压DP)
  • 原文地址:https://www.cnblogs.com/HDK2016/p/7159918.html
Copyright © 2011-2022 走看看