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

使用Spring的声明式事务----Annotation注解方式

程序员文章站 2022-05-21 09:28:47
...

这里列一个小的demo工程,直接利用Spring的jdbcTemplate访问Mysql数据库。

工程结构:

使用Spring的声明式事务----Annotation注解方式
            
    
    博客分类: 声明式事务SpringJava Spring声明式事务Annotation 
 

数据库中的tbl_student表结构如下:

使用Spring的声明式事务----Annotation注解方式
            
    
    博客分类: 声明式事务SpringJava Spring声明式事务Annotation 

 

数据实体类Student.java代码如下: 

package com.mysrc.entity;

import java.sql.Date;

public class Student {
	private int id;
	private String name;
	private Date birth;
	private float score;

	public Student() {

	}

	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 Date getBirth() {
		return birth;
	}

	public void setBirth(Date birth) {
		this.birth = birth;
	}

	public float getScore() {
		return score;
	}

	public void setScore(float score) {
		this.score = score;
	}

	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", birth=" + birth
				+ ", score=" + score + "]";
	}

}

 

 

数据访问类StudentDao.java代码如下:

package com.mysrc.dao;

import java.util.List;

import org.springframework.jdbc.core.JdbcTemplate;

import com.mysrc.entity.Student;
import com.mysrc.entity.StudentRowMapper;

public class StudentDao {

	private JdbcTemplate jdbcTemplate;

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

	public Student getStudentById(int id) {
		return jdbcTemplate.queryForObject(
				"select * from tbl_student where id = ?", new Object[] { id },
				new StudentRowMapper());
	}

	public List<Student> getAllStudent() {
		return jdbcTemplate.query("select * from tbl_student",
				new StudentRowMapper());
	}

	public int insertStudent(Student student) {
		return jdbcTemplate.update(
				"insert into tbl_student(name,birth,score) values(?,?,?)",
				new Object[] { student.getName(), student.getBirth(),
						student.getScore() });
	}

	public int deleteStudent(int id) {
		return jdbcTemplate.update("delete from tbl_student where id = ? ",
				new Object[] { id });
	}

	public int updateStudent(Student student) {
		return jdbcTemplate.update(
				" update tbl_student set name=?,birth=?,score=? where id=? ",
				new Object[] { student.getName(), student.getBirth(),
						student.getScore(), student.getId() });
	}
}

 

服务类StudentService.java代码如下:

package com.mysrc.service;

import java.sql.Date;
import java.util.List;

import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.mysrc.dao.StudentDao;
import com.mysrc.entity.Student;

public class StudentService {
	private StudentDao dao;

	public void setDao(StudentDao dao) {
		this.dao = dao;
	}

	@Transactional(propagation = Propagation.NESTED, timeout = 1000, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, noRollbackFor = CustomRuntimeException.class)
	public void doComplexLogic() {

		// select
		List<Student> list = dao.getAllStudent();
		for (Student student : list) {
			System.out.println(student);
		}

		// update
		Student student = list.get(0);
		student.setName("zhejiang");
		dao.updateStudent(student);
		System.out.println("did update temporarily...");

		// int a = 9 / 0; // 遇到异常,整个事务回滚
		// 如果try catch捕获这个异常,那整个事务会顺利执行,不会回滚

		int b = 2;
		if (b > 1) {
			throw new CustomRuntimeException();
			// 事务不会回滚,也就是上面的update操作会提交
		}

		// insert
		student = new Student();
		student.setName("hello");
		student.setBirth(new Date(354778));
		student.setScore(78.9f);
		dao.insertStudent(student);
		System.out.println("did insert...");

		// delete
		dao.deleteStudent(3);
		System.out.println("did delete...");
	}

	class CustomRuntimeException extends RuntimeException {
		public CustomRuntimeException() {
			super();
		}

		public CustomRuntimeException(String msg) {
			super(msg);
		}
	}
}

 doComplexLogic()方法模拟一个复杂的数据库操作过程,方法上加上了@Transactional,其中的各个注解的属性后面再详细研究。网上有人说@Transactional 只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能,这个未验证。

 

Spring的上下文配置文件applicationContext.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
	xmlns:tx="http://www.springframework.org/schema/tx">

	<bean id="basicDataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="url"
			value="jdbc:mysql://127.0.0.1:3306/mytestdb?characterEncoding=utf8" />
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="username" value="root" />
		<property name="password" value="123456" />
		<property name="maxActive" value="100" />
		<property name="maxIdle" value="30" />
		<property name="maxWait" value="1000" />
		<property name="validationQuery" value="select 1" />
	</bean>

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

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

	<bean id="studentDao" class="com.mysrc.dao.StudentDao">
		<property name="jdbcTemplate">
			<ref bean="jdbcTemplate" />
		</property>
	</bean>

	<bean id="studentService" class="com.mysrc.service.StudentService">
		<property name="dao">
			<ref bean="studentDao" />
		</property>
	</bean>

	<tx:annotation-driven transaction-manager="transactionManager" />
	<!--这句话的作用是注册事务注解处理器 -->

</beans>

 

测试类MyTester.java代码如下:

package com.mysrc.test;

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

import com.mysrc.service.StudentService;

public class MyTester {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		StudentService studentService = (StudentService) context
				.getBean("studentService");
		studentService.doComplexLogic();
	}

}

 

@Transactional 的所有可选属性如下
属性 类型 默认值 说明
propagation  Propagation枚举  REQUIRED  事务传播属性
isolation  isolation枚举  DEFAULT  事务隔离级别
readOnly  boolean  false  是否只读
timeout  int  -1  超时(秒)
rollbackFor  Class[]  {}  需要回滚的异常类
rollbackForClassName  String[]  {}  需要回滚的异常类名
noRollbackFor  Class[]  {}  不需要回滚的异常类
noRollbackForClassName  String[]  {}  不需要回滚的异常类名

 

 

 

 整个eclipse工程代码文件在附件中。。

  • 使用Spring的声明式事务----Annotation注解方式
            
    
    博客分类: 声明式事务SpringJava Spring声明式事务Annotation 
  • 大小: 27.3 KB
  • 使用Spring的声明式事务----Annotation注解方式
            
    
    博客分类: 声明式事务SpringJava Spring声明式事务Annotation 
  • 大小: 16.6 KB
  • 使用Spring的声明式事务----Annotation注解方式
            
    
    博客分类: 声明式事务SpringJava Spring声明式事务Annotation 
  • 大小: 28.4 KB