Spring数据库事务管理

一.简单事务管理

  • 用@Transaction 配置事务

配置文件

spring.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:p="http://www.springframework.org/schema/p"
	xmlns:stat="http://www.alibaba.com/schema/stat"
	xmlns:context="http://www.springframework.org/schema/context"
	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.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
		http://www.alibaba.com/schema/stat http://www.alibaba.com/schema/stat.xsd">

<context:component-scan base-package="com.qyc.*"></context:component-scan>

<context:property-placeholder location="db.properties"/>

<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
	<property name="username" value="${jdbc.username}"></property>
	<property name="password" value="${jdbc.password}"></property>
	<property name="url" value="${jdbc.url}"></property>
	<property name="driverClassName" value="${jdbc.driverClassName}"></property>
</bean>

<bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
	<property name="configLocation" value="classpath:mybatis.xml"></property>
	<property name="dataSource" ref="dataSource"></property>
</bean>

<bean id="mapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
	<property name="mapperInterface" value="com.qyc.mapper.Mapper"></property>
	<property name="sqlSessionFactory" ref="SqlSessionFactory"></property>
</bean>

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

<!-- 使用@Transaction配置事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qyc.mapper.Mapper">
	<select id="selectAllStudents" resultType="com.qyc.pojo.Student">
		select * from stu
	</select>
	<insert id="insertStudent" parameterType="com.qyc.pojo.Student">
		insert into stu (name,password)value(#{name},#{password})
	</insert>
</mapper>

mybatis.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-config.dtd">
 


<configuration>
<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
		<mappers>
			<mapper class="com.qyc.mapper.Mapper"/>
		</mappers>

</configuration>

 

 

1.1插入单个数据

service.java

package com.qyc.StudentServiceImpl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.qyc.StudentService.StudentService;
import com.qyc.mapper.Mapper;
import com.qyc.pojo.Student;
@Service
public class StudentServiceImpl implements StudentService{
@Autowired
private Mapper mapper;

	@Override
	@Transactional(propagation=Propagation.REQUIRES,isolation=Isolation.READ_COMMITTED)
	public int insertStudent(Student student) {
		int i = mapper.insertStudent(student);
		System.out.println("返回值为"+i);
		return 1;
	}

}

TestDemo.java

package com.qyc.test;


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

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

import com.qyc.StudentService.StudentListService;
import com.qyc.StudentService.StudentService;
import com.qyc.pojo.Student;

public class TestDemo {
	public static void main(String[] args) {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-basis.xml");
		StudentService serviceImpl = (StudentService) applicationContext.getBean("studentServiceImpl");
		Student student = new Student("强月城", "123456789");
		System.out.println(serviceImlp.insertStudent(student));
	}
}

 

1.2插入多条数据(总结三种类型)实际可以有多种处理方法

  • 插入多条数据的方法调用的是插入一条数据的方法
  • 注意@Transaction里的参数
  • 传播行为
  • REQUIRED spring默认传播行为,当方法调用时,如果不存在当前事务,那么创建事务,如果之前方法已经存在事务,则沿用之前的事务
  • REQUIRES_NEW 无论是否存在,都会创建新事务
  • NESTED 嵌套事务,调用方法如果抛出异常,只回滚自己内部执行的SQL,而不回滚主方法SQL

1.2.1 NO1

  • 在插入单个数据方法中,捕获RuntimeException异常

 

一条

package com.qyc.StudentServiceImpl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.qyc.StudentService.StudentService;
import com.qyc.mapper.Mapper;
import com.qyc.pojo.Student;
@Service
public class StudentServiceImpl implements StudentService{
@Autowired
private Mapper mapper;

	@Override
	@Transactional(propagation=Propagation.REQUIRES_NEW,isolation=Isolation.READ_COMMITTED)
	public int insertStudent(Student student) {
		int i = 0;
		// TODO Auto-generated method stub
		try {
			i = mapper.insertStudent(student);
		} catch (Exception e) {
//			throw new RuntimeException(e);
			// TODO: handle exception
			return 0;
			
		}
		System.out.println("返回值为"+i);
		return 1;
	}

}

多条

package com.qyc.StudentServiceImpl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.qyc.StudentService.StudentListService;
import com.qyc.StudentService.StudentService;
import com.qyc.mapper.Mapper;
import com.qyc.pojo.Student;

@Service
public class StudentListServiceImpl implements StudentListService {

	private int count = 0;
	@Autowired
	@Qualifier("studentServiceImpl")
	private StudentService studentServiceImpl;

	@Override
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
	public int insertListStudent(List<Student> list) {
		// TODO Auto-generated method stub
		for (Student student : list) {
			count += studentServiceImpl.insertStudent(student);
		}
		return count;
	}

}

TestDemo.java

package com.qyc.test;


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

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

import com.qyc.StudentService.StudentListService;
import com.qyc.StudentService.StudentService;
import com.qyc.pojo.Student;

public class TestDemo {
	public static void main(String[] args) {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-basis.xml");
		StudentListService serviceImlp = (StudentListService) applicationContext.getBean("studentListServiceImpl");
		List<Student> list = new ArrayList<Student>();
		list.add(new Student("qyc", "qqqyyyc"));
		list.add(new Student(null, "123456789"));
		list.add(new Student("qcc", "qqqccc"));
		
		System.out.println(serviceImlp.insertListStudent(list));
	}
}

1.2.2No2

  • 在main方法中设置try catch模块包围调用的方法
  • 一条抛异常
  • 把一条的@transaction 参数设置为REQUIRES_NEW

 

1.2.3No3

  • 在main方法中设置try catch模块
  • 把一条的@transaction 参数设置为REQUIRED
  • 一条抛异常

 

总结:

结构上面源码意义

  • requires new  不抛 2条
  • requires new  抛    1条
  • required           不抛 2条
  • required           抛  0条

 

二.多表操作

2.1俩种情况

2.1.1  

  • 需要在后面的方法加trycatch语句  
  • 抛   throw new RuntimeException(e);
package com.qyc.StudentServiceImpl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.qyc.StudentService.StudentService;
import com.qyc.mapper.Mapper;
import com.qyc.pojo.Student;
@Service
public class StudentServiceImpl implements StudentService{
@Autowired
private Mapper mapper;

	@Override
	@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.READ_COMMITTED)
	public int insertStudent(Student student) {
		int i = 0;
		// TODO Auto-generated method stub
		try {
			i = mapper.insertStudent(student);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		System.out.println("返回值为"+i);
		return i;
	}

}
package com.qyc.shopping;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.qyc.StudentService.StudentService;
import com.qyc.StudentServiceImpl.StudentServiceImpl;
import com.qyc.mapper.Mapper;
import com.qyc.pojo.Record;
import com.qyc.pojo.Student;
import com.qyc.pojo.WareHouse;
@Service
public class ShoppingImpl implements Shopping{
@Autowired 
Mapper mapper;

@Autowired
StudentService studentServiceImpl;

@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.READ_COMMITTED)
	@Override
	public void scdd() {
		// TODO Auto-generated method stub
		int sum = mapper.selectKc("001");
		if(sum>0) {
			mapper.updateKc(new WareHouse("001",sum-1));
			
			studentServiceImpl.insertStudent(new Student("商品", "ceshi"));
			
//			mapper.insertJl(new Record(null,"001"));
			
			
		}else {
			System.out.println("库存不足");
		}
	}

}

 

2.1.2

  • throw new RuntimeException(e); 注释掉就可以
  • 要在主方法里用try catch包围

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值