Spring提供了声明事务处理机制,它基于AOP的实现,无需编写任何事务管理代码,所有的工作全在配置文件中完成,与业务代码完全分离,配置即可用,降低了开发和维护的难度。
一、想要事务管理,就要对数据修改
1、在cn.bdqn下的dao层,创建UserMapper.xml文件,写入update修改语句,抽接口
<update id="updatePwdById" parameterType="User">update smbms_user set userPassword = #{userPassword} where id = #{id}</update>抽接口public int updatePwdById(User user);
2、在service层,创建UserServiceImpl,写入updatePwdById方法,抽接口
@Transactional(rollbackFor=Exception.class)public int updatePwdById(User user){int i = userMapper.updatePwdById(user);System.out.println(1/0);return i;}抽接口public int updatePwdById(User user);
3、在添加事务前,先测试(UserMapperTest),如果是好使的,就可以修改
4、配置文件,加入事务管理器
①、id=”txManager” ②、注解管理事务
<!-- 添加/配置Spring的事务管理器 --><bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!-- name="dataSource"属性 ref="dataSource"数据源--><property name="dataSource" ref="dataSource"></property></bean><!-- 启用注解管理事务 --><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
测试前,在原先配置文件中引入子配置文件,再测试UserMapperTest
根配置文件中<!-- 引入相关的子配置文件 525--><import resource="applicationContext-mybatis.xml"/>子配置文件中<?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:aop="http://www.springframework.org/schema/aop"xmlns:p="http://www.springframework.org/schema/p"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.2.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.2.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.2.xsd"><!-- spring整合mybatis --><!-- 1、声明bean 加载database.properties配置文件--><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="location"><value>classpath:database.properties</value></property></bean><!-- 配置数据源 --><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><property name="driverClassName"><value>${driver}</value></property><property name="url"><value>${url}</value></property><property name="username"><value>${user}</value></property><property name="password"><value>${password}</value></property></bean><!-- 声明sqlSessionFactory --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"></property><property name="configLocation"><value>classpath:mybatis-config.xml</value></property></bean><!-- 扫描指定Mapper的包,使其注册为Mapper对象 --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage"><value>cn.bdqn.dao</value></property></bean></beans>
