上文Spring JDBC 声明式事务采用注解配置形式,步骤如下
因为是基于AOP,所以必须引入aop和aspectjweaver:
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.3.30version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.3.30version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.33version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.13.2version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>5.3.30version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aopartifactId>
<version>5.3.30version>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.9.7version>
dependency>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-classicartifactId>
<version>1.3.12version>
dependency>
主要步骤如下:
1、配置数据源和TransactionManager事务管理器
2、启用注解形式声明式事务
例如:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:contex="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<contex:property-placeholder location="application.properties"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
bean>
<contex:component-scan base-package="com.hirain"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
beans>
package com.hirain.service;
import com.hirain.dao.EmployeeDao;
import com.hirain.entity.Employee;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
@Service
//声明式事务核心注解,放在类上时,将声明式事务配置应用于当前类的所有方法,默认事务传播为REQUIRED
@Transactional(propagation = Propagation.REQUIRED)
public class EmployeeService {
@Autowired
private EmployeeDao employeeDao;
@Autowired
private DataSourceTransactionManager transactionManager;
public void batchInsert() {
for (int i = 0; i < 10; i++) {
if (i==3){
throw new RuntimeException("生成员工数据异常");
}
Employee employee = new Employee();
employee.setEmployeeId(80+i);
employee.setName("新员工"+i);
employee.setDepartmentId(2l);
employee.setTitle("客服");
employee.setLevel(1);
employeeDao.insert(employee);
}
}
//单独将getEmployeeById设置为不开启事务,只读(直接写在方法上的注解方式优先级最高,会覆盖卸载类上的注解)
@Transactional(propagation = Propagation.NOT_SUPPORTED,readOnly = true)
public Employee getEmployeeById(int id) {
Employee employee = employeeDao.findById(id);
return employee;
}
//...getter and setter
}
package com.hirain.dao;
import com.hirain.entity.Employee;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
@Repository
public class EmployeeDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public Employee findById(long id){
String sql = "select * from adm_employee where employee_id=?";
Employee employee = jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<Employee>(Employee.class));
return employee;
}
public int insert(Employee employee){
String sql="insert into adm_employee (employee_id,name,department_id,title,level) values(?,?,?,?,?)";
int rows = jdbcTemplate.update(sql,new Object[]{
employee.getEmployeeId(),
employee.getName(),
employee.getDepartmentId(),
employee.getTitle(),
employee.getLevel()
});
return rows;
}
public int update(Employee employee){
String sql="UPDATE adm_employee SET name=?,department_id=?,title=?,level=? WHERE employee_id=?";
int rows = jdbcTemplate.update(sql,new Object[]{
employee.getName(),
employee.getDepartmentId(),
employee.getTitle(),
employee.getLevel(),
employee.getEmployeeId()
});
return rows;
}
public int delete(long id){
String sql="delete from adm_employee where employee_id=?";
int rows = jdbcTemplate.update(sql,new Object[]{id});
return rows;
}
public EmployeeDao() {
}
//...getter and setter
}
import com.hirain.dao.EmployeeDao;
import com.hirain.entity.Employee;
import com.hirain.service.EmployeeService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class) // 使用 Spring 的测试运行器
@ContextConfiguration(locations = {"classpath:applicationContext.xml"}) // 加载 Spring 配置文件
public class JDBCTemplateTest {
@Autowired
private EmployeeService employeeService;
@Test
public void testBantchInsert() {
employeeService.batchInsert();
}
}