Spring5(23) —— 回顾事务
程序员文章站
2022-07-12 10:07:44
...
1.回顾事务
- 事务特性:要么都成功,要么都失败
- 事务在项目开发中十分重要,涉及到数据一致性问题,不能马虎
- 它用于确保数据一致性
事务的ACID原则
- 原子性:事务不可分割
- 一致性:事务执行不管成不成功,所有人的数据要一致;比如转账,那么参与转账双方的钱的总和应该保持不变
- 隔离性:操作同一数据的不同事务之间相互独立,互不干扰
- 持久性:事务成功之后,其结果必须影响数据库中的数据;即使事务失败,也要求使用某种机制恢复数据
2.代码实现
1.项目搭建
首先我们再来回顾一下spring整合mybatis
-
创建新项目:Spring-11-Transaction
-
子model依赖添加
<?xml version="1.0" encoding="UTF-8"?> <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"> <parent> <artifactId>Spring-Study</artifactId> <groupId>com.thhh</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>Spring-11-Transaction</artifactId> <dependencies> <!--junit依赖--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <!--数据库依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <!--mybatis依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.2</version> </dependency> <!--spring依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.8.RELEASE</version> </dependency> <!--spring操作数据库,需要再导入一个spring-jdbc这个依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.8.RELEASE</version> </dependency> <!--AOP织入包,简单理解,支持切入点表达式等等--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency> <!--mybatis-spring整合依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.5</version> </dependency> <!--lombok依赖--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> </dependencies> </project>
-
创建实体类
package com.thhh.pojo; import lombok.Data; @Data public class User { private int id; private String name; private String pwd; }
-
有了实体类就为它创建一个mapper接口
package com.thhh.mapper; import com.thhh.pojo.User; import java.util.List; public interface UserMapper { public List<User> queryUserList(); }
-
有了mapper接口就为它创建一个mapper.xml
<?xml version="1.0" encoding="UTF8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.thhh.mapper.UserMapper"> <select id="queryUserList" resultType="user"> select * from mybatis.user </select> </mapper>
-
有了mapper.xml就去mybatis核心配置文件中注册,注意这一点,原来单独使用mybatis的时候,配置文件中的内容比较多,现在我们将spring和mybatis进行了整合,mybatis中一般只剩下了typealiases和setting节点的配置,其他配置都迁移到spring容器中
<?xml version="1.0" encoding="UTF8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!--类型别名节点--> <typeAliases> <package name="com.thhh.pojo"/><!--直接包扫描,我们可以使用类名,首字母大小写都可以--> </typeAliases> </configuration>
-
整合mybatis,创建spring配置文件,这里我们为了规范,先创建一个整个mybatis的配置文件spring-dao.xml,再创建一个总的配置文件applicationContext.xml;spring-dao.xml负责整合mybatis(即只装配两个bean,dataSource和sqlSessionFactory),applicationContext.xml用于引入spring-dao.xml和装配bean(其他的bean都装配到这个spring容器中)
- spring-dao.xml
<?xml version="1.0" encoding="UTF8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--数据源datasources:是呀spring的数据源替换mybatis的配置--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&useSSL=false"/> <property name="username" value="root"/> <property name="password" value="123"/> </bean> <!--sqlsessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!--绑定mybatis配置文件--> <property name="configLocation" value="classpath:mybatis-config.xml"/><!--这样两个配置文件就联动起来了--> <property name="mapperLocations" value="classpath:com/thhh/mapper/*.xml"/><!--配置注册mapper.xml,对应mybatis中的注册mapper节点--> </bean> </beans>
- applicationContext.xml
<?xml version="1.0" encoding="UTF8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--导入整合mybatis的子容器,最后所有的容器会整合成一个大容器--> <import resource="spring-dao.xml"/> <!--装配bean--> <!--方式2配置sqlsession--> <bean id="userMapperImpl" class="com.thhh.mapper.UserMapperImpl"> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean> </beans>
-
整合spring和mybatis的时候我们需要新增一个mapper接口的实现类来封装mybatis的操作,即UserMapperImpl
package com.thhh.mapper; import com.thhh.pojo.User; import org.mybatis.spring.support.SqlSessionDaoSupport; import java.util.List; public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{ @Override public List<User> queryUserList() { return getSqlSession().getMapper(UserMapper.class).queryUserList(); } }
-
测试
import com.thhh.mapper.UserMapper; import com.thhh.pojo.User; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.List; public class MyTest { @Test public void test01(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserMapper userMapper = context.getBean("userMapperImpl", UserMapper.class); List<User> userList = userMapper.queryUserList(); for (User user : userList) { System.out.println(user); } } }
2.代码实现
需求:制造错误,用于认识spring操作中不使用事务的危险性
- 添加一个新增和删除用户操作
package com.thhh.mapper; import com.thhh.pojo.User; import org.apache.ibatis.annotations.Param; import java.util.List; public interface UserMapper { //1、查询所有用户 public List<User> queryUserList(); //2、新增用户 public int addUser(User user);//非基本数据类型不要写@Param注解,否则会报错 //3、删除用户 public int deleteUser(@Param("id") int id); }
- 修改实现类
package com.thhh.mapper; import com.thhh.pojo.User; import org.mybatis.spring.support.SqlSessionDaoSupport; import java.util.List; public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{ @Override public List<User> queryUserList() { return getSqlSession().getMapper(UserMapper.class).queryUserList(); } @Override public int addUser(User user) { return getSqlSession().getMapper(UserMapper.class).addUser(user); } @Override public int deleteUser(int id) { return getSqlSession().getMapper(UserMapper.class).deleteUser(id); } }
- 去mapper.xml中编写SQL
<?xml version="1.0" encoding="UTF8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.thhh.mapper.UserMapper"> <!--1、查询用户--> <select id="queryUserList" resultType="user"> select * from mybatis.user </select> <!--2、新增用户--> <insert id="addUser" parameterType="user"> insert into mybatis.user (id, name, pwd) values (#{id},#{name},#{pwd}); </insert> <!--3、删除用户--> <delete id="deleteUser"> delete from mybatis.user where id=#{id} </delete> </mapper>
- 制造一个错误,把delete关键字后面添加一个"S",那么delete操作显然使用报错的
- 修改查询实现的mybatis对应的代码
@Override public List<User> queryUserList() { User user = new User(10,"10号","123"); UserMapper userMapper = getSqlSession().getMapper(UserMapper.class); userMapper.addUser(user); deleteUser(10); return userMapper.queryUserList(); }
推荐阅读
-
spring5 源码深度解析----- 事务的回滚和提交(100%理解事务)
-
Spring5学习9——(Spring事务)
-
Spring5学习(六)Spring 事务
-
Spring5(23) —— 回顾事务
-
四、Spring5框架之事务
-
spring5 源码深度解析----- @Transactional注解的声明式事物介绍(100%理解事务)
-
spring5 源码深度解析----- 事务增强器(100%理解事务)
-
Exchange 事务和Exchange 数据库回顾
-
Exchange 事务和Exchange 数据库回顾
-
spring5 源码深度解析----- 事务的回滚和提交(100%理解事务)