您的位置:首页 > 编程语言 > Java开发

spring-transaction-事务

2015-12-20 01:42 489 查看
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&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&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);
}
}
}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: