欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring数据库事务管理

程序员文章站 2022-03-30 10:14:16
...

一.简单事务管理

  • 用@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

Spring数据库事务管理

  • 在插入单个数据方法中,捕获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

Spring数据库事务管理

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

 

1.2.3No3

Spring数据库事务管理

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

 

总结:

结构上面源码意义

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

 

二.多表操作

2.1俩种情况

2.1.1  

Spring数据库事务管理

  • 需要在后面的方法加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;
	}

}

2.1.2

Spring数据库事务管理

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