spring-transaction-事务

spring-in-action-jdbc-transaction代码

同时成功,同时失败。事务分为编码式事务和声明式事务。

package com.SimpleJdbcTemplate.Dao;

import com.SimpleJdbcTemplate.domian.Family;

import java.util.List;

/**
 * Created by cuimiao on 15/12/13.
 */
public interface FamilyDao {
    public void insert(Family family);
    public void update(Family family);
    public void delete();
    public List<Family> selectAll(Family family);
    public void batchInsert(List<Family> familyList);

}
package com.SimpleJdbcTemplate.domian;

/**
 * Created by cuimiao on 15/12/13.
 */
public class Family {
    private int id;
    private String name;
    private String role;

    public Family() {
    }

    public Family(int id, String name, String role) {
        this.id = id;
        this.name = name;
        this.role = role;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }
}
package com.SimpleJdbcTemplate.Impl;

import com.SimpleJdbcTemplate.Dao.FamilyDao;
import com.SimpleJdbcTemplate.domian.Family;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

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

/**
 * Created by cuimiao on 15/12/19.
 */
//@Component
//@Transactional
public class FamilyDaoImplTransaction implements FamilyDao{
//    @Autowired
//    @Qualifier("jdbc")
    private JdbcTemplate jdbcTemplate;

    //    @Autowired
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

//    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void insert(Family family){
        String sql = "insert into famiXXly (name,role) values (?,?)";//这故意写错了,产生异常
        jdbcTemplate.update(sql, family.getName(), family.getRole());
    }
    public void delete(){
        String sql = "delete from family where 1 order by id DESC limit 1";
        jdbcTemplate.update(sql);
    }

    public void update(Family family){
        String sql = "UPDATE family SET role = ? WHERE 1 ORDER BY id DESC limit 1";
        jdbcTemplate.update(sql, family.getRole());
    }

    public List<Family> selectAll(Family family){
        String sql = "SELECT * FROM family";
        List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
        return jdbcTemplate.query(sql, BeanPropertyRowMapper.newInstance(Family.class));
    }

    public void batchInsert(List<Family> familyList){
        String sql = "insert into family(name,role)values(?,?)";
        List<Object[]> parameters = new ArrayList<Object[]>();
        for (Family f : familyList) {
            parameters.add(new Object[] { f.getName(), f.getRole() });
        }
        jdbcTemplate.batchUpdate(sql, parameters);
    }

}
package com.SimpleJdbcTemplate.service;

import com.SimpleJdbcTemplate.Dao.FamilyDao;
import com.SimpleJdbcTemplate.domian.Family;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.List;

/**
 * Created by cuimiao on 15/12/19.
 */
public class FamilyService {

    private TransactionTemplate transactionTemplate;

    private FamilyDao familyDao;

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    public void setFamilyDao(FamilyDao familyDao) {
        this.familyDao = familyDao;
    }

    public void batchInsert(final List<Family> familyList){
        transactionTemplate.execute(new TransactionCallback<Void>() {

            public Void doInTransaction(TransactionStatus txStatus) {
                try {
                    familyDao.batchInsert(familyList);
                    //error
                    familyDao.insert(new Family());
                } catch (Exception e) {
                    txStatus.setRollbackOnly();
                    System.out.println("batchInsert ERROR");
                }
                return null;
            }
        });
    }

    public List<Family> selectAll(final Family family){
        return transactionTemplate.execute(new TransactionCallback<List<Family>>() {

            public List<Family> doInTransaction(TransactionStatus txStatus) {
                try {
                    return familyDao.selectAll(family);
                } catch (Exception e) {
                    txStatus.setRollbackOnly();
                    System.out.println("batchInsert ERROR");
                }
                return null;
            }
        });
    }

    public void insert(final Family family){
        transactionTemplate.execute(new TransactionCallback<Void>() {

            public Void doInTransaction(TransactionStatus txStatus) {
                try {
                    familyDao.insert(family);
                } catch (Exception e) {
                    txStatus.setRollbackOnly();
                    System.out.println("batchInsert ERROR");
                }
                return null;
            }
        });
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

       <!--familyService中有impl,有transactionTemplate,transactionTemplate有transactionManager,transactionManager有dataSource-->
       <bean id="familyService" class="com.SimpleJdbcTemplate.service.FamilyService">
              <property name="familyDao" ref="familyDaoImplTransaction"/>
              <property name="transactionTemplate" ref="transactionTemplate"/>
       </bean>

       <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
               <property name="transactionManager" ref="transactionManager"/>
       </bean>

       <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
              <property name="dataSource" ref="dataSource"/>
       </bean>


       <!--familyDao的impl,有JdbcTemplate,JdbcTemplate有dataSource-->
       <bean id="familyDaoImplTransaction" class="com.SimpleJdbcTemplate.Impl.FamilyDaoImplTransaction">
              <property name="jdbcTemplate" ref="jdbc"/>
       </bean>

       <bean id="jdbc" class="org.springframework.jdbc.core.JdbcTemplate">
              <property name="dataSource" ref="dataSource"/>
              <!--<constructor-arg name="dataSource" ref="dataSource"/>-->
       </bean>

       <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
              <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
              <property name="url" value="jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&amp;characterEncoding=utf-8"/>
              <property name="username" value="root"/>
              <property name="password" value="nieyijing214"/>
              <property name="initialSize" value="5"/>
              <property name="maxActive" value="10"/>
       </bean>
</beans>
TransactionCallback为回调方法,在方法里进行了TransactionStatus对异常等的处理,包括rollback,如果没有异常就commit了。
package TestTransactionTemplate;

import com.SimpleJdbcTemplate.domian.Family;
import com.SimpleJdbcTemplate.service.FamilyService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

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

/**
 * Created by cuimiao on 15/12/19.
 */
public class TestSimpleJdbcTransaction {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-simple-dao-transaction.xml");
        FamilyService familyService = (FamilyService) context.getBean("familyService");

        List<Family> familyList = new ArrayList<Family>();
        familyList.add(new Family(0, "崔淼", "老公"));
        familyList.add(new Family(0, "聂绎静", "老婆"));
        familyList.add(new Family(0, "嘿嘿", "小三"));
        //三条数据是正确的,一条是假的
        familyService.batchInsert(familyList);

//        familyService.insert(new Family(0, "儿子", "崔小淼"));

        List<Family> resultList = familyService.selectAll(new Family());

        for(Family family:resultList){
            long id = family.getId();
            String name = family.getName();
            String role = family.getRole();
            System.out.println(id + "    " + name + "    " + role);
        }
    }
}

 


以上是编码式事务,如果为声明式,以下面注释@Transaction为例;
package com.SimpleJdbcTemplate.service;

import com.SimpleJdbcTemplate.Dao.FamilyDao;
import com.SimpleJdbcTemplate.domian.Family;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Created by cuimiao on 15/12/19.
 */
//@Component
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class FamilyAnnotaitonService {
//    @Autowired
//    @Qualifier("familyDaoImplTransaction")
//    @Autowired
    private FamilyDao familyDao;

    public void setFamilyDao(FamilyDao familyDao) {
        this.familyDao = familyDao;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void insert(Family family){
        familyDao.insert(family);
        familyDao.insert(family);
        familyDao.insert(family);
//        throw new RuntimeException("ASDFDFDF");

    }

    public void delete(){
        familyDao.delete();
    }

    public void update(Family family){
        familyDao.update(family);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public  void batchInsert(List<Family> familyList){
        familyDao.batchInsert(familyList);
//        try {
//            familyDao.insert(new Family(0, "1", "2"));
//        } catch (Exception e) {
//            System.out.println("ASDFASDF");
//        }
        familyDao.insert(new Family(0, "1", "2"));
    }

    public List<Family> selectAll(Family family){
        return familyDao.selectAll(family);
    }
}

主要注意一下事务的rollbackfor,因为主要针对的是RuntimeException;

还有边界,如果再@Transaction的方法内部进行了catch则不会回滚,因为transactionManager是靠aop进行实现的,所以要抛出异常才能执行,要不然不会rollback,会commit,所有必须抛出来。下面是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: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.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

       <context:annotation-config/>
       <context:component-scan base-package="com"/>
       <tx:annotation-driven transaction-manager="trManager" proxy-target-class="true"/>

       <bean id="trManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
              <property name="dataSource" ref="dataSource"/>
       </bean>

       <bean id="familyAnnotaitonService" class="com.SimpleJdbcTemplate.service.FamilyAnnotaitonService">
              <property name="familyDao" ref="familyDaoImplTransaction"/>
       </bean>

       <bean id="familyDaoImplTransaction" class="com.SimpleJdbcTemplate.Impl.FamilyDaoImplTransaction">
              <property name="jdbcTemplate" ref="jdbc"/>
       </bean>

       <bean id="jdbc" class="org.springframework.jdbc.core.JdbcTemplate">
              <property name="dataSource" ref="dataSource"/>
              <!--<constructor-arg name="dataSource" ref="dataSource"/>-->
       </bean>

       <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
              <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
              <property name="url" value="jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&amp;characterEncoding=utf-8"/>
              <property name="username" value="root"/>
              <property name="password" value="nieyijing214"/>
              <property name="initialSize" value="5"/>
              <property name="maxActive" value="10"/>
       </bean>
</beans>
package TestTransactionTemplate;

import com.SimpleJdbcTemplate.domian.Family;
import com.SimpleJdbcTemplate.service.FamilyAnnotaitonService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

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

/**
 * Created by cuimiao on 15/12/19.
 */
public class TestSimpleJdbcTransactionAnnotation {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-simple-dao-transaction-annotation.xml");
        FamilyAnnotaitonService familyService = (FamilyAnnotaitonService) context.getBean("familyAnnotaitonService");

        List<Family> familyList = new ArrayList<Family>();
        familyList.add(new Family(0, "崔淼", "老公"));
        familyList.add(new Family(0, "聂绎静", "老婆"));
        familyList.add(new Family(0, "嘿嘿", "小三"));
        //三条数据是正确的,一条是假的
        try {
            familyService.batchInsert(familyList);
        } catch (Exception e) {
            System.out.println("BATCH INSERT ERROR");
        }

//        familyService.insert(new Family(0, "儿子", "崔小淼"));

        List<Family> resultList = familyService.selectAll(new Family());

        for(Family family:resultList){
            long id = family.getId();
            String name = family.getName();
            String role = family.getRole();
            System.out.println(id + "    " + name + "    " + role);
        }
    }
}

 



posted @ 2015-12-20 01:42  damiao_hungry  阅读(313)  评论(0编辑  收藏  举报