基于注解的Spring事务配置

spring采用@Transactional注解进行事务申明,@Transactional既可以在方法上申明,也可以在类上申明,方法申明优先于类申明。

1、pom配置

包括spring核心包引入以及spring jdbc包引入。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.coshaho</groupId>
<artifactId>coshaho-model</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>coshaho-model</name>
<url>http://maven.apache.org</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.4.RELEASE</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.4.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.4.RELEASE</version>
</dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency> <!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

2、spring.xml配置

需要引入tx标签,初始化DataSourceTransactionManager实例,并把@Transactional和DataSourceTransactionManager实例关联起来。

<?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: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.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"
> <!-- 注解注入 -->
<context:component-scan base-package="com.coshaho.*" /> <!-- 引入jdbc配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 使用spring初始化DataSource -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 使用JdbcTemplate封装DataSource -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 定义事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!--使用注释事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>

3、测试代码

定义数据库表对象以及映射关系

package com.coshaho.vo;

public class User
{
private int id;
private String name;
private int age;
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
package com.coshaho.dao;

import java.sql.ResultSet;
import java.sql.SQLException; import org.springframework.jdbc.core.RowMapper; import com.coshaho.vo.User; public class UserMapper implements RowMapper<User>
{
public User mapRow(ResultSet rs, int rowNum) throws SQLException
{
User user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setAge(rs.getInt("age"));
return user;
}
}

我们定义user表字段name为唯一字段,用事务代码插入两行相同记录,看看能否成功。

package com.coshaho.dao;

import com.coshaho.vo.User;

public interface UserDao
{
public void create(String name, int age);
public User query(int id);
public void create2User();
}
package com.coshaho.dao;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import com.coshaho.vo.User; @Component
public class UserDaoImpl implements UserDao
{
@Autowired
private JdbcTemplate jdbcTemplate; @Transactional
public void create(String name, int age)
{
jdbcTemplate.update("insert into user(name, age) values (?, ?)",
name, age);
} public User query(int id)
{
List<User> user = jdbcTemplate.query("select * from user where id=" + id,
new UserMapper());
return user.get(0);
} @Transactional
public void create2User()
{
create("b", 1);
create("b", 1);
} private static ApplicationContext context;
public static void main(String[] args)
{
String xmlpath = "spring.xml";
context = new ClassPathXmlApplicationContext(xmlpath);
UserDao userDao = (UserDao) context.getBean("userDaoImpl");
userDao.create("a", 1);
userDao.create2User();
}
}

执行结果

基于注解的Spring事务配置

可以看到,在同一个事务中依次插入两条相同记录,都没有插入成功。

上一篇:Plugin with id 'com.android.application' not found.


下一篇:jsp上传excel文件并导入数据库