Spring(三)事务处理、整合Mybatis

一、事务处理

1.事务传播行为

一共七种:

  • PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是 最常见的选择。
  • PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
  • PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。
  • PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
  • PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
  • PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED 类似的操作。

2.事务隔离级别

Isolation 属性一共支持五种事务设置,具体介绍如下:

  • DEFAULT 使用数据库设置的隔离级别 ( 默认 ) ,由 DBA 默认的设置来决定隔离级别 .
  • READ_UNCOMMITTED 未提交读 会出现脏读、不可重复读、幻读 ( 隔离级别最低,并发性能高 )
  • READ_COMMITTED 已提交读 会出现不可重复读、幻读问题(锁定正在读取的行)
  • REPEATABLE_READ 可重复读 会出幻读(锁定所读取的所有行)
  • SERIALIZABLE 可序列化 保证所有的情况不会发生(锁表)

3.几种事务出现问题的区别

不可重复读的重点是修改
同样的条件 , 你读取过的数据 , 再次读取出来发现值不一样了
幻读的重点在于新增或者删除
同样的条件 , 第 1 次和第 2 次读出来的记录数不一样

4.Spring在TransactionDefinition接口中定义这些属性

在TransactionDefinition接口中定义了五个不同的事务隔离级别

  • ISOLATION_DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应
  • ISOLATION_READ_UNCOMMITTED 这是事务最低的隔离级别,它允许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读
  • ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。
  • ISOLATION_REPEATABLE_READ 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
  • ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。

5.Spring中的声明式事务控制

Spring中控制事务的方式采用声明式的事务控制。为我们提供了不同的事务控制器的切面(注意:spring的事物控制器就是一个aop,如果面试时问你是否用spring的aop 。一定要回答用过,起码事务上用到了。)

6.配置Spring的基于dataSourse的事务控制器,适用于jdbc、mybatis,DataSourceAransactionManager:基于数据源的事务控制的切面

7.代码实现

1.导入jar包:

spring-jdbc.jar
spring-tx.jar
spring-aop.jar
2.在spring的配置文件中配置事务

<?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:tx="http://www.springframework.org/schema/tx" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">
     <!-- 需要在配置文件的头中开启tx的命名空间 -->
     <!-- 先配置基于dataSource的事务管理器的切面(AOP)-->
     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 该切面需要一个datasource -->
        <property name="dataSource">
            <ref bean="dataSource"/>
        </property>
     </bean>
    <!-- 配置事物传播行为以及事物隔离级别 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- 
            name:需要参与到事物控制中的方法名。可以使用*来通配
            propagation:事物的传播行为。REQUIRED 必须要运行在一个事务中
            isolation:事物的隔离级别 。DEFAULT以数据默认的隔离级别为主。
            read-only:只读事物。只读并不会做事物提交与回滚。他会优化查询执行的效率。所以如果不是DML操作。建议都需要拥有只读事物
             -->
            <tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT"/>
            <tx:method name="drop*" propagation="REQUIRED"/>
            <tx:method name="modify*" propagation="REQUIRED"/>
            <tx:method name="*" read-only="true"/>
        </tx:attributes>
    </tx:advice>
    <!-- 配置切点 -->
    <aop:config>
        <aop:pointcut expression="execution(* com.tinner.service.impl.*.*(..))" id="mypointcut"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="mypointcut"/>
    </aop:config>
</beans>

二、整合mybatis

1.在实现Spring与Mybatis的整合时,需要导入两个框架的jar包。注意:spring与mybatis整合时,需要额外导入一个非常重要的jar包 spring-mybatis.jar

2.Spring中提供三种方式

2.1 sqlSessionTemplate

Autowire属性:自动装配
1。byName通过名称完成自动注入。要求注入与被注入的属性的名称相同
2。byType 通过类型完成自动注入。要求名称可以不相同,但是类型必须是同类型,或者是父类,或者已实现的接口类型。
default-autowire :<beans>标签中的该属性表示全局性的自动装配的设置

<?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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
        <!-- 通过命名空间配置解析配置文件的工具类 -->
       <context:property-placeholder location="/db.properties"/>
     <!-- 配置数据源。dbcp  c3p0 druid。。。 -->
<!-- 配置数据源 dataSource -->
    <!-- <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="maxActive" value="10" />
        <property name="minIdle" value="5" />
    </bean> -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/test001"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
    
    <!-- 配置创建mybatis上下文对象的工具类 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" >
        <!-- 配置datasource -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 导入其他配置文件 -->
        <property name="mapperLocations" value="com/tinner/pojo/*.xml"/>
    </bean>
    
    <!-- 配置sqlsessiontemplate -->
    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <!-- 通过构造方法完成sqlsessionfactory的注入 -->
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
    
    <!-- 配置userdao -->
    <bean id="userDao" class="com.tinner.dao.impl.UserDaoImpl" autowire="byName"/>
</beans>
2.2 SqlSessionDaoSupport方式

配置文件:

<!-- 配置创建mybatis上下文对象的工具类 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" >
        <!-- 配置datasource -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 导入其他配置文件 -->
        <property name="mapperLocations" value="com/tinner/pojo/*.xml"/>
    </bean>
    <!-- 配置userdao -->
    <bean id="userDao" class="com.tinner.dao.impl.UserDaoImpl" >
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>

代码:

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
    //将SqlSessionFactory交给SqlSessionDaoSupport
    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
        super.setSqlSessionFactory(sqlSessionFactory);
    }
    @Override
    public void insertUser(Users user) {
        this.getSqlSession().insert("com.tinner.pojo.Users.insertUser", user);
    }
}
2.3 使用代理类生成接口实现类的方式
<?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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
        <!-- 通过命名空间配置解析配置文件的工具类 -->
       <context:property-placeholder location="/db.properties"/>
     <!-- 配置数据源。dbcp  c3p0 druid。。。 -->
<!-- 配置数据源 dataSource -->
    <!-- <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="maxActive" value="10" />
        <property name="minIdle" value="5" />
    </bean> -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/test001"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
    <!-- 配置创建mybatis上下文对象的工具类 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" >
        <!-- 配置datasource -->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 配置扫描接口与映射配置文件对象  该对象会去创建接口的代理对象。并且根据接口的名称作为该对象的默认名称-->
    <bean  class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.tinner.mapper"/>
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>    
    </bean>
</beans>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容

  • 很多人喜欢这篇文章,特此同步过来 由浅入深谈论spring事务 前言 这篇其实也要归纳到《常识》系列中,但这重点又...
    码农戏码阅读 4,726评论 2 59
  • Spring 事务属性分析 事务管理对于企业应用而言至关重要。它保证了用户的每一次操作都是可靠的,即便出现了异常的...
    壹点零阅读 1,301评论 0 2
  • Spring 事务传播特性和隔离级别 事务是处理逻辑原子性的保证,作为单个逻辑单元执行一系列操作,要么执行完成要么...
    自负的鱼阅读 8,952评论 1 33
  • aop配置和事务的配置 环境 jdk1.7 tomcat7.0 spring3.1.1 hibernate4.1....
    playman阅读 1,343评论 0 2
  • 怀旻看着大央宫内正中央摆放的华服,那是皇姐生前的朝装。灰黑色暗花云纹长裙,墨绿的宽袖对襟衫上用金丝银线绣着大朵盛开...
    指染阅读 187评论 0 0