事务管理

学习 同时被 3 个专栏收录
31 篇文章 0 订阅
2 篇文章 0 订阅
1 篇文章 0 订阅

事务管理

标签: 事务管理 mysql


好看
对登录注册程序添加事务管理:

pom.xml添加:

        <!--aop使用aspectj切入点表达式-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>4.1.6.RELEASE</version>
        </dependency>

spring-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:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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/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
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--引入配置文件-->
    <context:property-placeholder
            ignore-resource-not-found="true"
            location="classpath:/db.properties"/>

    <!--数据源配置-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${password}"/>

        <property name="maxActive" value="${jdbc.pool.maxActive}"/>

        <property name="maxIdle" value="${jdbc.pool.maxIdle}"/>

        <property name="minIdle" value="${jdbc.pool.minIdle}"/>

        <property name="maxWait" value="${jdbc.pool.maxWait}"/>

        <!-- 检查链接是否关闭的sql -->
        <property name="validationQuery" value="select 1"/>
        <property name="testOnBorrow" value="true"/>

    </bean>

    <!--mybatis与spring的整合,不需要mybatis自己的配置映射文件-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--配置连接数据库数据源-->
        <property name="dataSource" ref="dataSource"/>
        <!--配置Mapper文件所在位置-->
        <property name="mapperLocations" value="classpath:/mybatis/*Mapper.xml"/>
    </bean>

    <!--MapperScannerConfigurer将会扫描basePackage并自动装配-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.wenjie.dao"/>
        <!--<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>-->
    </bean>

添加事务管理配置:

    <!-- 配置JDBC数据源的局部事务管理器,使用DataSourceTransactionManager 类 -->
    <!-- 该类实现PlatformTransactionManager接口,是针对采用数据源连接的特定实现-->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 配置DataSourceTransactionManager时需要依注入DataSource的引用 -->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--配置事务增强处理,指定事务管理器-->
    <tx:advice id="myAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" rollback-for="Exception" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
    <!-- 配置一个切入点,匹配com.wenjie.service.impl包下所有类,所有方法的执行 -->
    <aop:config>
        <aop:pointcut id="myPointcut" expression="execution(* com.wenjie.service.impl.*.*(..))"/>
        <!-- 通知器,指定在myPointcut切入点应用myAdvice事务增强处理 -->
        <aop:advisor advice-ref="myAdvice" pointcut-ref="myPointcut"/>
    </aop:config>
    <!--由于需要事务控制,所以不能让spring自动扫描注入,spring会把它当做普通bean对象-->
    <bean id="loginService" class="com.wenjie.service.impl.LoginServiceImpl"/>
    <bean id="registerService" class="com.wenjie.service.impl.RegisterServiceImpl"/>
</beans>

Propagation取值:

REQUIRED(默认值):在有transaction状态下执行;如当前没有transaction,则创建新的transaction;

SUPPORTS:如当前有transaction,则在transaction状态下执行;如果当前没有transaction,在无transaction状态下执行;

MANDATORY:必须在有transaction状态下执行,如果当前没有transaction,则抛出异常IllegalTransactionStateException;

REQUIRES_NEW:创建新的transaction并执行;如果当前已有transaction,则将当前transaction挂起;

NOT_SUPPORTED:在无transaction状态下执行;如果当前已有transaction,则将当前transaction挂起;

NEVER:在无transaction状态下执行;如果当前已有transaction,则抛出异常IllegalTransactionStateException。

spring-mvc.xml注释service层自动注入

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

    <!--自动扫描且只扫描@Controller-->
    <context:component-scan base-package="com.wenjie.controller">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--对service进行注入-->
    <!--<context:component-scan base-package="com.wenjie.service"/>-->

    <!-- 激活基于注解的配置 @RequestMapping, @ExceptionHandler,数据绑定 ,@NumberFormat ,
    @DateTimeFormat ,@Controller ,@Valid ,@RequestBody ,@ResponseBody等  -->
    <mvc:annotation-driven/>

    <!-- 视图解析器配置,使用内部资源视图解析器,使用位于/WEB-INF/pages/目录下的后缀为jsp的文件作为视图 -->
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/pages/"
          p:suffix=".jsp"/>

</beans>

演示RegisterServiceImpl

现在如果RegisterServiceImpl和LoginServiceImpl有异常外抛,则会执行回滚,数据库里面不会进行操作。

package com.wenjie.service.impl;

import com.wenjie.dao.UserDao;
import com.wenjie.entity.User;
import com.wenjie.service.RegisterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * Created by Fate on 2016/7/4.
 */
public class RegisterServiceImpl implements RegisterService {
    @Autowired
    UserDao userDao;

    public boolean register(String username, String password, String age) throws Exception {
        User result = userDao.findByName(username);
        if (result != null) {
            return false;
        }
        User user = new User();
        user.setName(username);
        user.setPassword(password);
        user.setAge(age);
        user.setId(100);
        int re = userDao.createUser(user);
        userDao.createUser(user);
        return re == 1;
    }
}

利用主键唯一进行测试:

正常事务管理,报错:

1

数据库没有改变:

2

去掉事务管理:

3

也报错:

4

但是数据库插入了第一条数据:

5

注意:

. 如果你在RegisterServiceImpl和LoginServiceImpl中catch 住异常,不再抛出,异常没办法到事务管理器中,就不会触发回滚操作。

. 在配置了事务代理的Service业务逻辑实现类的方法里,若将异常捕获,并且在catch块中不对事务做显式提交(或其他应该做的操作如关闭资源等)=生吞掉异常!

. spring的事务边界是在调用业务方法之前开始的,业务方法执行完毕之后来执行commit or rollback(Spring默认取决于是否抛出runtime异常或unchecked异常)。如果抛出runtime exception并在你的业务方法中没有catch到的话,事务就会回滚。

. 所以一般不需要在业务方法中catch异常,如果非要catch,在做完你想做的工作后(比如关闭文件等)一定要抛出runtime exception,否则spring会将你的操作commit,这样就会产生脏数据,你的catch代码就是画蛇添足。

. 因此可以在上层做try……catch异常的捕捉处理

. 这里实际上反应了为什么要引入Service层的概念。
将事务管理放在Service层而不是dao层。可以将多次不同dao的操作放到同一个事务里。

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值