就是把一系列操作看成一个整体,要么都成功,要么都失败,他在项目开发中十分重要,涉及数据一致性问题。
事务ACID原则
- 原子性
- 一致性
- 隔离性
- 持久性
搭建环境
package com.lei.mapper;
import com.lei.pojo.User;
import java.util.List;
public interface UserMapper {
public List<User> selectUser();
public int addUser(User user);
public int deleteUser(int id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lei.mapper.UserMapper">
<select id="selectUser" resultType="user">
select * from user;
</select>
<insert id="addUser" parameterType="user">
insert into user values(#{id},#{name},#{pwd})
</insert>
<delete id="deleteUser" parameterType="int">
deletes from user where id = #{id}
</delete>
</mapper>
package com.lei.mapper;
import com.lei.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper {
public List<User> selectUser() {
User user = new User(4,"你好","sasas");
SqlSession sqlSession = getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.addUser(user);
mapper.deleteUser(4);
return mapper.selectUser();
}
public int addUser(User user) {
return getSqlSession().getMapper(UserMapper.class).addUser(user);
}
public int deleteUser(int id) {
return getSqlSession().getMapper(UserMapper.class).deleteUser(id);
}
}
import com.lei.mapper.UserMapper;
import com.lei.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 test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper userMapper = context.getBean("UserMapper", UserMapper.class);
List<User> users = userMapper.selectUser();
for (User user:users) {
System.out.println(user);
}
}
}
此处在selectUser中的操作就相当于一个整体,我们故意将删除语句写错,然后查看效果。
查询失败,因为删除失败了,但是这条数据还是被插进去了,原则上,一个事务如果出错,那整个操作都会失败,这不符合我们预期效果。
配置文件中相关配置
//配置声明式事务
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
<!-- 结合AOP实现事务织入-->
<!-- 配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="query" read-only="true"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置事务切入-->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.lei.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
再次运行程序:
依然报错,但是数据并没有被插入。