什么是事务

一组操作,要么都成功,要么都失败。

  • 声明式事务:AOP
  • 编程式事务:需要在代码中进行事务管理

使用Spring声明式事务

Mapper接口实现类

  1. public interface IEmpMapper {
  2. List<Emp> select();
  3. int insert(Emp emp);
  4. int delete(@Param("id")int id);
  5. }
  6. //继承SqlSessionDaoSupport
  7. public class EmpMapper2 extends SqlSessionDaoSupport implements IEmpMapper{
  8. //在调用select时,会先添加,在删除,最后查询
  9. @Override
  10. public List<Emp> select() {
  11. insert(new Emp(1,"问问",56,"男","999@qq.com",new Dept(2)));
  12. delete(2);
  13. return getSqlSession().getMapper(IEmpMapper.class).select();
  14. }
  15. @Override
  16. public int insert(Emp emp) {
  17. return getSqlSession().getMapper(IEmpMapper.class).insert(emp);
  18. }
  19. @Override
  20. public int delete(int id) {
  21. return getSqlSession().getMapper(IEmpMapper.class).delete(id);
  22. }
  23. }

Mapper.xml映射文件
可以看到我故意写错了delete语句。如果执行上面的select()方法,添加成功过后,删除会失败。
这时候,数据库有被添加的数据,但是要删除的数据却还在。
应该用事务把select()方法看作是一个整体,全部成功就成功,一个失败了,全部回滚都失败。

  1. <mapper namespace="com.lyd.mapper.IEmpMapper">
  2. <select id="select" resultType="Emp">
  3. select*from t_emp
  4. </select>
  5. <insert id="insert">
  6. insert into t_emp values(null,#{empName},#{age},#{sex},#{email},#{dept.did})
  7. </insert>
  8. <delete id="delete">
  9. deletes from t_emp where eid = #{id}
  10. </delete>
  11. </mapper>

在Spring配置文件里面配置事务

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. https://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/aop
  9. https://www.springframework.org/schema/aop/spring-aop.xsd
  10. http://www.springframework.org/schema/tx
  11. https://www.springframework.org/schema/tx/spring-tx.xsd">
  12. <!--
  13. DataSource:
  14. 使用Spring的数据源替换Mybatis的配置,c3p0 dbcp druid
  15. 这里使用Spring提供的JDBC
  16. -->
  17. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  18. <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  19. <property name="url" value="jdbc:mysql://localhost:3306/mybatisdb?useUnicode=true&amp;characterEncoding=utf8"/>
  20. <property name="username" value="root"/>
  21. <property name="password" value="123456"/>
  22. </bean>
  23. <!--
  24. sqlSessionFactory:
  25. -->
  26. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  27. <property name="dataSource" ref="dataSource" />
  28. <!--绑定Mybatis配置文件-->
  29. <property name="configLocation" value="classpath:mybatis-config.xml"/>
  30. <property name="mapperLocations" value="classpath:com/lyd/mapper/*.xml"/>
  31. </bean>
  32. <!--配置声明式事务-->
  33. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  34. <property name="dataSource" ref="dataSource"/>
  35. </bean>
  36. <!--结合AOP实现事务的织入-->
  37. <!--配置事务通知-->
  38. <tx:advice id="txAdvice" transaction-manager="transactionManager">
  39. <!--给哪些方法配置事务-->
  40. <!---->
  41. <tx:attributes>
  42. <tx:method name="query" propagation="REQUIRED"/>
  43. </tx:attributes>
  44. </tx:advice>
  45. <!--配置事务的切入-->
  46. <aop:config>
  47. <aop:pointcut id="txPointCut" expression="execution(* com.lyd.mapper.*.*(..))"/>
  48. <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
  49. </aop:config>
  50. <!--
  51. 上面都是固定的写法:
  52. 下面都是才是自己编写的实现类,有多少实现类就编写多少bean
  53. 注入sqlSession对象
  54. -->
  55. <bean id="empMapper2" class="com.lyd.mapper.EmpMapper2">
  56. <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
  57. </bean>
  58. </beans>

现在测试,哪怕insert()方法没问题,delete()方法失败了,最终insert()也没有真正的加入数据到数据库

  1. @Test
  2. public void test1() throws IOException {
  3. ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
  4. IEmpMapper iempMapper =context.getBean("empMapper2",IEmpMapper.class);
  5. List<Emp> emps = iempMapper.select();
  6. for (Emp emp: emps) {
  7. System.out.println(emp.toString());
  8. }
  9. }