• 基于注解的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();
        }
    }

    执行结果

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

  • 相关阅读:
    java native方法
    linux free命令
    gdb使用
    java锁——wait,notify,synchronized
    java面试——问题回溯
    (转)每天一个linux命令(44):top命令
    java面试——jvm
    java面试——多线程
    数据库面试总结
    CMakeLists.txt使用
  • 原文地址:https://www.cnblogs.com/coshaho/p/10460234.html
Copyright © 2020-2023  润新知