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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java jsonfield_@JSONField使用[通俗易懂]

    参考博客:http://www.cnblogs.com/yucy/p/9057049.html1.经常遇到这种情况,传过来json的key名和我们javaBean的属性名不一样,导致接收不到:Child类用来接收传过来的json串:packagecom.test.dto;importorg.apache.commons.lang3.builder.ToStringBuilder;importorg…

    2022年4月6日
    159
  • 银河麒麟v10.1_银河麒麟v10系统

    银河麒麟v10.1_银河麒麟v10系统银河麒麟v10下载(服务器版桌面版)-2022-03-16更新银河麒麟桌面操作系统V10和银河麒麟高级服务器操作系统V10,分别推出了飞腾、鲲鹏、龙芯、申威、海光、兆芯六个版本银河麒麟高级服务器操作系统V10银河麒麟桌面操作系统V10…

    2022年10月16日
    16
  • Javaweb 聊天室

    Javaweb 聊天室Javaweb聊天室前言java课程结束了之后,老师要求我们用java做一个关于聊天室的课程设计,于是我就想做一个web应用,在这里只是纯分享,如果想要源码的,可以在评论里说。一、实验目的做一个Javaweb聊天室系统1.实现登录功能2.注册功能3.发送聊天内容功能4.接收消息5…

    2022年6月22日
    38
  • 详解Linux双网卡绑定之bond0「建议收藏」

    1、什么是bond?  网卡bond是通过多张网卡绑定为一个逻辑网卡,实现本地网卡的冗余,带宽扩容和负载均衡,在生产场景中是一种常用的技术。Kernels2.4.12及以后的版本均供bonding模块,以前的版本可以通过patch实现。2、实现原理:  网卡工作在混杂(promisc)模式,接收到达网卡的所有数据包,tcpdump工作用的也是混杂模式(promisc),将两块网卡的MAC地址…

    2022年4月1日
    66
  • Qt Creator下载和安装(详细教程)

    Qt Creator下载和安装(详细教程)简介Qt是跨平台的图形开发库,目前由Digia全资子公司QtCompany独立运营,官方网址:http://www.qt.io/也可以访问Qt项目域名:http://qt-project.org/Qt本身支持众多操作系统。从通用操作系统Linux、Windows,到手机系统Android、iOS、WinPhone,嵌入式系统支持QNX、VxWorks,应用非常广泛。基于Qt的

    2022年5月13日
    51
  • Android碎片化之屏幕适配

    Android碎片化之屏幕适配Android 碎片化之屏幕适配现如今 因 Android 系统的开放性 市场上出现了不同厂商出厂的各种 android 版本 分辨率 型号等设备 那对我们开发来说 碎片化绝对是一个让人头脑炸裂的问题 Android 系统碎片化 Android 机型屏幕尺寸碎片化 Android 屏幕分辨率碎片化 市面上安卓手机的主流屏幕尺寸种类繁多 就算搞定了屏幕尺寸问题 各种分辨率又让人眼花缭乱 面对测试同学抛过来的适配问

    2026年1月27日
    1

发表回复

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

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