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

论坛 期权论坛 脚本     
匿名网站用户   2020-12-21 05:18   1309   0

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

工程结构:


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

数据实体类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工程代码文件在附件中。。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP