Spring集成MyBatis 事务管理

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

大家好,又见面了,我是你们的朋友全栈君。

前言

        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时,你会发现数据库一直是锁定状态,直到你程序执行完。如下图:

Spring集成MyBatis 事务管理

 

二、基于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;
    }

复制代码

 

  参考资料

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/142778.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SQLyog安装成功步骤(附带码),2021版最新

    SQLyog安装成功步骤(附带码),2021版最新一、SQLyong安装:先是一路next,自己改变一下安装路径,点自己激活:Name自己取,下一行输入dd987f34-f358-4894-bd0f-21f3f04be9c1即可二、各种类型的算法高频面试题汇总:https://blog.csdn.net/qq_40262372/article/details/112556249三.群里已有字节、滴滴大佬,可帮忙内推!也欢迎其他大厂的工作人士进群!帮忙内推~QQ群:725936761四、B站视频讲解如何三个月学习JAVA..

    2022年5月11日
    86
  • java字符串切分_Java字符串分割(转)[通俗易懂]

    java字符串切分_Java字符串分割(转)[通俗易懂]java.lang.String的split()方法,JDK1.4orlaterpublicString[]split(Stringregex,intlimit)示例代码publicclassStringSplit{publicstaticvoidmain(String[]args){StringsourceStr=”1,2,3,4,5″;String[]s…

    2022年6月21日
    30
  • VS导入没有.sln文件的项目[通俗易懂]

    VS导入没有.sln文件的项目[通俗易懂]关于在VS中导入没有.sln文件的.net项目     导入的是一个网站项目,步骤是先创建一个空白的解决方案,再在解决方案中点击右键,添加一个现有网站项目,再选择相应的项目文件,即可进行网站的运行。如果在运行过程中出现xxx.cs文件中不存在该类型的命名或命名空间,那么极有可能是相应的.net框架版本不一致导致,所以在点击该项目的属性页中调整相应的框架版本,即可进行相应的网站项目运行。…

    2022年5月25日
    113
  • 电商平台安全_跨境电商有哪些平台

    电商平台安全_跨境电商有哪些平台电商网站安全之威胁一、越权操作凡是仅靠传入参数就进行数据库查询的功能即存在越权。越权类型:1、平行越权(订单,留言,送货地址,修改信息,修改密码…)2、垂直越权(修改信息,修改密码,创建用户..)3、越权查询4、越权修改5、直接越权6、间接越权7、……越权操作的危害:泄漏用户数据,非法篡改他人业务,权限提升。无法通过WAF以及常规手段发现。越权形式影响越权查看订单/保单订单数据…

    2022年10月1日
    6
  • css-day06笔记-学成在线网页制作&chrome调试工具&Chrome提示的常见布局错误「建议收藏」

    css-day06笔记-学成在线网页制作&chrome调试工具&Chrome提示的常见布局错误「建议收藏」typora-copy-images-to:media第01阶段.WEB基础:css-day06笔记-学成在线网页制作一、学成在线页面制作目标理解能够说写单页面我们基本的流程能说出常见的css初始化语句能说出我们CSS属性书写顺序应用能利用ps切图能引入外部样式表能把psd文件转换为html页面学成在线的目的就是为了串联前面的所有知识。来一个春晚大联…

    2022年5月28日
    52
  • Vagrant安装完lnmp后,配置linux和windows共享文件并配置虚拟主机访问项目

    Vagrant安装完lnmp后,配置linux和windows共享文件并配置虚拟主机访问项目

    2021年11月8日
    48

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号