SpringMVC+MyBatis 事务管理一

前言

spring事务管理包含两种情况,编程式事务、声明式事务。而声明式事务又包括基于注解@Transactional和tx+aop的方式。那么本文先分析编程式注解事务和基于注解的声明式事务。 编程式事务管理使用TransactionTemplate或者PlatformTransactionManager。对于编程式事务spring推荐使用TransactionTemplate。

一、编程式事务

spring事务特性

spring中所有的事务策略类都继承自org.springframework.transaction.PlatformTransactionManager接口

public interface PlatformTransactionManager {

    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

    void commit(TransactionStatus status) throws TransactionException;

    void rollback(TransactionStatus status) throws TransactionException;

}

编程式事务TransactionTemplate需要手动在代码中处理事务,一般不推荐使用,也不符合spring的思想,因为它直接耦合代码,但各有利弊。先看下TransactionTemplate的源码。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

public class TransactionTemplate extends DefaultTransactionDefinition

        implements TransactionOperations, InitializingBean {

    

    protected final Log logger = LogFactory.getLog(getClass());

    private PlatformTransactionManager transactionManager;

    public TransactionTemplate() {

    }

    public TransactionTemplate(PlatformTransactionManager transactionManager) {

        this.transactionManager = transactionManager;

    }

    

    public TransactionTemplate(PlatformTransactionManager transactionManager, TransactionDefinition transactionDefinition) {

        super(transactionDefinition);

        this.transactionManager = transactionManager;

    }

    public void setTransactionManager(PlatformTransactionManager transactionManager) {

        this.transactionManager = transactionManager;

    }

    public PlatformTransactionManager getTransactionManager() {

        return this.transactionManager;

    }

    @Override

    public void afterPropertiesSet() {

        if (this.transactionManager == null) {

            throw new IllegalArgumentException("Property ‘transactionManager‘ is required");

        }

    }

    @Override

    public <T> T execute(TransactionCallback<T> action) throws TransactionException {

        if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {

            return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);

        }

        else {

            TransactionStatus status = this.transactionManager.getTransaction(this);

            T result;

            try {

                result = action.doInTransaction(status);

            }

            catch (RuntimeException ex) {

                // Transactional code threw application exception -> rollback

                rollbackOnException(status, ex);

                throw ex;

            }

            catch (Error err) {

                // Transactional code threw error -> rollback

                rollbackOnException(status, err);

                throw err;

            }

            catch (Throwable ex) {

                // Transactional code threw unexpected exception -> rollback

                rollbackOnException(status, ex);

                throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");

            }

            this.transactionManager.commit(status);

            return result;

        }

    }

    

    private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {

        logger.debug("Initiating transaction rollback on application exception", ex);

        try {

            this.transactionManager.rollback(status);

        }

        catch (TransactionSystemException ex2) {

            logger.error("Application exception overridden by rollback exception", ex);

            ex2.initApplicationException(ex);

            throw ex2;

        }

        catch (RuntimeException ex2) {

            logger.error("Application exception overridden by rollback exception", ex);

            throw ex2;

        }

        catch (Error err) {

            logger.error("Application exception overridden by rollback error", ex);

            throw err;

        }

    }

}

  从上面的代码可以看到核心方法是execute,该方法入参TransactionCallback<T>。查看TransactionCallback源码:


1

2

3

public interface TransactionCallback<T> {

    T doInTransaction(TransactionStatus status);

}

 那么以上两个源码可以确定我们使用编程式事务管理的方式也就是自己需要重写doInTransaction()。OK,那么我们手动使用TransactionTemplate处理下。

1、先配置transactionmanager

 <!--事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

2、配置transactionTemplate

 <!--编程式事务,推荐使用TransactionTemplate-->
    <bean id="transactionTemplate"
          class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>

3、业务代码处理

 @Autowired
    private TransactionTemplate transactionTemplate;

    public int insertUser2(final User user) {
        Integer i= (Integer) this.transactionTemplate.execute(new TransactionCallback() {
            public Object doInTransaction(TransactionStatus transactionStatus) {

                int i = userMapper.insertUser(user);
                if (i > 0) {
                    System.out.println("success");
                }
                int j = 10 / 0;

                return i;

            }
        });

        return i;
    }

业务代码中我们使用by zero的异常故意抛出,你会发现能继续打印success,当你断点debug时,你会发现数据库一直是锁定状态,直到你程序执行完。如下图:

二、基于Transactional注解的事务管理

当前应该是使用最清爽的事务管理方式了,也符合spring的理念,非入侵代码的方式。

1、配置

 <!--事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

 <!-- 使用注解事务,需要添加Transactional注解属性 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

 <!--启用最新的注解器、映射器-->
    <mvc:annotation-driven/>

2、配置后只需要在要处理的地方加上Transactional注解,而且Transactional注解的方式可以应用在类上,也可以应用在方法上,当然只针对public方法。

3、业务代码处理

  @Transactional
    public int insertUser(User user) {
        int i = userMapper.insertUser(user);
        if (i > 0) {
            System.out.println("success");
        }
        int j = 10 / 0;

        return i;
    }

参考资料

https://www.cnblogs.com/sword-successful/p/7274929.html

http://www.cnblogs.com/wyisprogramming/p/6944878.html

http://www.cnblogs.com/xusir/p/3650522.html

SpringMVC项目中配置xml时一些和命名空间相关的问题,如mvc:annotation-driven的前缀 "mvc"未绑定

Q1.元素 "mvc:annotation-driven" 的前缀 "mvc"未绑定

办法:在spring-servlet.xml文件里使用<mvc>开头的标签时,忘记引入了命名空间。在xml的beans里面加入如下代码即可

  1. xmlns:mvc="http://www.springframework.org/schema/mvc"
  2. http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd

Q2.通配符的匹配很全面, 但无法找到元素 ‘mvc:annotation-driven‘ 的声明

原因是:虽然在xml文件上方声明了mvc,但没有配置此声明对应的文件信息,正确配置如下:

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

意思就是,mvc声明用http://www.springframework.org/schema/mvc/spring-mvc.xsd这个文件来解析

https://blog.csdn.net/chanewx/article/details/57397360

原文地址:https://www.cnblogs.com/roak/p/12681106.html

时间: 2024-08-11 02:35:42

SpringMVC+MyBatis 事务管理一的相关文章

spring + springmvc+ mybatis 事务管理及控制

<?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&

SpringMVC+MyBatis 事务管理二

前言 上篇主要从编程式事务和声明式事务注解的形式来了解了事务,而这篇我们针对AOP的方式来实现事务.先回顾下事务的基础知识事务的隔离级别和事务的传播行为.使用aop 配置事务时注意引用aspectjweaver,要不然程序启动起来就会报错,找不到相关类 事务隔离级别 隔离级别是指若干个并发的事务之间的隔离程度.TransactionDefinition 接口中定义了五个表示隔离级别的常量: TransactionDefinition.ISOLATION_DEFAULT:这是默认值,表示使用底层数

spring+mybatis事务管理

spring+mybatis事务管理 最近在和朋友做一个项目,考虑用springmvc+mybatis来做,之前在公司工作吧,对于数据库这块的配置也有人再弄,最近因为这个项目,我就上网学习了一些关于数据库配置这方面的东西吧,今天给大家分享一下关于spring+mybatis管理事务这方面得知识吧. 先说说spring管理事务的集中方式,我所了解的有两种:第一种是编程式事务管理,第二种是声明式事务管理,而声明式事务管理中又有两种,一种是配置方式,另一种是声明式.我们在工作中一般都使用声明式事务管理

《深入理解mybatis原理》 MyBatis事务管理机制

MyBatis作为Java语言的数据库框架,对数据库的事务管理是其非常重要的一个方面.本文将讲述MyBatis的事务管理的实现机制.首先介绍MyBatis的事务Transaction的接口设计以及其不同实现JdbcTransaction 和 ManagedTransaction:接着,从MyBatis的XML配置文件入手,讲解MyBatis事务工厂的创建和维护,进而阐述了MyBatis事务的创建和使用:最后分析JdbcTransaction和ManagedTransaction的实现和二者的不同

spring,mybatis事务管理配置与@Transactional注解使用

spring,mybatis事务管理配置与@Transactional注解使用[转] 概述事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性.Spring Framework对事务管理提供了一致的抽象,其特点如下: 为不同的事务API提供一致的编程模型,比如JTA(Java Transaction API), JDBC, Hibernate, JPA(Java Persistence API和JDO(Java Data Objects) 支持声明式事务管理,特别是基

spring,mybatis事务管理配置与@Transactional注解使用[转]

spring,mybatis事务管理配置与@Transactional注解使用[转] spring,mybatis事务管理配置与@Transactional注解使用 概述事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性.Spring Framework对事务管理提供了一致的抽象,其特点如下: 为不同的事务API提供一致的编程模型,比如JTA(Java Transaction API), JDBC, Hibernate, JPA(Java Persistence A

使用SpringMVC+mybatis+事务控制+JSON 配置最简单WEB

最近在总结一些项目的基础知识,根据公司最近的一些意向和技术路线,初步整理了一个简单的配置例子     1.使用springmvc代替strutsMVC     2.使用请求json数据串的方式代替传统返回jspview.     3.使用Mybatis代替hibernate 在这些要求的基础上,做了一些尝试.    现在将配置文件整理如下:   目录结构如下:    1.web.xml <?xml version="1.0" encoding="UTF-8"?

springboot mybatis 事务管理

本文主要讲述springboot提供的声明式的事务管理机制. 一.一些概念 声明式的事务管理是基于AOP的,在springboot中可以通过@Transactional注解的方式获得支持,这种方式的优点是: 1)非侵入式,业务逻辑不受事务管理代码的污染. 2)方法级别的事务回滚,合理划分方法的粒度可以做到符合各种业务场景的事务管理. 本文使用目前最常用的mybatis框架来配置springboot的事务管理机制.下面进入配置方法介绍. 二.springboot mybatis事务配置 1.看一下

Mybatis 事务管理

mybatis的事务和数据源有着非常密切的联系.上文讲述了mybatis的数据源,本文要讲述的便是mybatis的事物 1.事务的分类 我们还是已一段xml配置文件为例 <environments default="development"> <environment id="development"> <transactionManager type="JDBC"> <property name=&qu