Spring提供了声明事务处理机制,它基于AOP的实现,无需编写任何事务管理代码,所有的工作全在配置文件中完成,与业务代码完全分离,配置即可用,降低了开发和维护的难度。

一、想要事务管理,就要对数据修改

1、在cn.bdqn下的dao层,创建UserMapper.xml文件,写入update修改语句,抽接口

  1. <update id="updatePwdById" parameterType="User">
  2. update smbms_user set userPassword = #{userPassword} where id = #{id}
  3. </update>
  4. 抽接口
  5. public int updatePwdById(User user);

2、在service层,创建UserServiceImpl,写入updatePwdById方法,抽接口

  1. @Transactional(rollbackFor=Exception.class)
  2. public int updatePwdById(User user){
  3. int i = userMapper.updatePwdById(user);
  4. System.out.println(1/0);
  5. return i;
  6. }
  7. 抽接口
  8. public int updatePwdById(User user);

3、在添加事务前,先测试(UserMapperTest),如果是好使的,就可以修改
4、配置文件,加入事务管理器
①、id=”txManager” ②、注解管理事务

  1. <!-- 添加/配置Spring的事务管理器 -->
  2. <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  3. <!-- name="dataSource"属性 ref="dataSource"数据源-->
  4. <property name="dataSource" ref="dataSource"></property>
  5. </bean>
  6. <!-- 启用注解管理事务 -->
  7. <tx:annotation-driven transaction-manager="txManager" />

二、声明式事务的注解添加方式

@Transactional

5、到userServiceImpl中的方法上面加入@Transactional(rollbackFor=Exception.class),添加回滚
6、测试,如果测试之前,方法上有@Transactional和回滚,测试时,密码不会 被修改;
如果测试之前,方法上没有@Transactional和回滚,测试时,密码才会 被修改;
7、开启回滚事务的作用?
//开启事务(添加回滚)—作用:方法内部可以调用多个Dao,多个sql语句加入同一事务,满足ACID的原则,
//如果发生异常,无论在什么位置,方法内所有已经执行了的sql语句均会发生回滚操作,从而保证事务的原子性,
//一致性,持久性。而隔离性需要看数据库的隔离级别去确定

三、事务的5种隔离级别

1、DEFAULT:默认值

2、READ_UNCOMMITED:未提交读——无锁——————-允许脏读、不可重复读、幻读

3、READ_COMMITED:提交读—————会话锁——————-允许不可重复读、幻读

4、REPEATABLE_READ:可重复读———行级锁——————-允许幻读

5、SERIALIZABLE:串行读———————表级锁——————都不允许

四、产生的三种问题

脏读:事务A读取到事务B还没有提交的事务

不可重复读:两次读取的数据不一致

幻读:事务A修改了数据,事务B添加了一条数据,事务A查看是修改好了,但是事务B修改后,事务A再次查看怎么多了一条

具体详细信息,可查看知识库—数据库

五、配置文件的拆分

拆分的策略,有两种

1、如果一个开发人员负责一个模块,采用公用配置(数据源、事务等)+每个模块的单独配置文件(dao、Service、和web控制器等)
2、如果开发是按照分层进行的分工,采用公用配置(数据源、事务等)+DAOBean配置+业务逻辑Bean配置+Web控制器配置的形式。

拆分实现

首先新建applicationContext-Mybatis.xml
将配置文件中的Spring整合mybatis的代码切入applicationContext,xml
image.png
测试前,在原先配置文件中引入子配置文件,再测试UserMapperTest

  1. 根配置文件中
  2. <!-- 引入相关的子配置文件 525-->
  3. <import resource="applicationContext-mybatis.xml"/>
  4. 子配置文件中
  5. <?xml version="1.0" encoding="UTF-8"?>
  6. <beans xmlns="http://www.springframework.org/schema/beans"
  7. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  8. xmlns:aop="http://www.springframework.org/schema/aop"
  9. xmlns:p="http://www.springframework.org/schema/p"
  10. xmlns:tx="http://www.springframework.org/schema/tx"
  11. xmlns:context="http://www.springframework.org/schema/context"
  12. xsi:schemaLocation="http://www.springframework.org/schema/beans
  13. http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  14. http://www.springframework.org/schema/context
  15. http://www.springframework.org/schema/context/spring-context-3.2.xsd
  16. http://www.springframework.org/schema/tx
  17. http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
  18. http://www.springframework.org/schema/aop
  19. http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
  20. <!-- spring整合mybatis -->
  21. <!-- 1、声明bean 加载database.properties配置文件-->
  22. <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  23. <property name="location">
  24. <value>classpath:database.properties</value>
  25. </property>
  26. </bean>
  27. <!-- 配置数据源 -->
  28. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  29. <property name="driverClassName">
  30. <value>${driver}</value>
  31. </property>
  32. <property name="url">
  33. <value>${url}</value>
  34. </property>
  35. <property name="username">
  36. <value>${user}</value>
  37. </property>
  38. <property name="password">
  39. <value>${password}</value>
  40. </property>
  41. </bean>
  42. <!-- 声明sqlSessionFactory -->
  43. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  44. <property name="dataSource" ref="dataSource">
  45. </property>
  46. <property name="configLocation">
  47. <value>classpath:mybatis-config.xml</value>
  48. </property>
  49. </bean>
  50. <!-- 扫描指定Mapper的包,使其注册为Mapper对象 -->
  51. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  52. <property name="basePackage">
  53. <value>cn.bdqn.dao</value>
  54. </property>
  55. </bean>
  56. </beans>