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


相关推荐

  • JMeter学习笔记–JMeter执行顺序规则

    JMeter学习笔记–JMeter执行顺序规则

    2021年9月2日
    74
  • orcle导入导出

    orcle导入导出CREATETABLES SZPrisonDATA D TABLESPANCE SZPrison DBF SIZE1000MEXT CREATEUSER amp userNameIDEN amp passwordDEFA

    2025年7月29日
    3
  • 网页制作实验步骤_web简易开发

    网页制作实验步骤_web简易开发web实验2制作简单网页(HTML+CSS)一、实验目的1.掌握文本样式的设置。2.掌握图像样式的设置。3.掌握各种媒体的插入方法。二、实验内容采用DIV+CSS,制作“在线电影”页面。三、操作提示1.新建网站的文件夹,网站图像素材保存在images文件夹中,媒体文件放在flash文件中。2.新建index.html页面,要求: 页面字体大小为14px,文本颜色为#000; 页面背景颜色为#edb8d2; 上下左右距均为0。3.利用div布局,宽度为900px,居中对齐。

    2022年10月13日
    4
  • 这也许是史上最有趣的破解软件合集

    这也许是史上最有趣的破解软件合集一,破解版百度网盘,下载速度超快,公众号回复【h01】即可获取。二,微信点赞工具,使用例子:新开的饭店呀,要你出示什么100个赞就可以吃霸王餐呀,根本不用徒劳朋友圈,直接用这软件就行,给你装备的机会,好好表演,公众号回复【h02】即可获取。三,微信群二维码采集助手,这个给那些微商需要引流的就很有作用啦,普通人可能用不到,公众号回复【h03】即可获取四,一款便捷图章制作工具,不想用PS,那这款软件就…

    2022年5月27日
    53
  • msfconsole使用教程_kali msfconsole

    msfconsole使用教程_kali msfconsole文章目录前言一、入侵步骤二、msfconsole常用命令总结前言MetasploitFramework是非常优秀的开源渗透测试框架。Metasploit渗透测试框架(MSF3.4)包含3功能模块:msfconsole、msfweb、msfupdate。msfupdate用于软件更新,建议使用前先进行更新,可以更新最新的漏洞库和利用代码。msfconsole是整个框架中最受欢迎的模块,个人感觉也是功能强大的模块,所有的功能都可以该模块下运行。msfweb是Metasploitframew.

    2025年9月25日
    7
  • docker导出镜像命令_docker save将容器保存为镜像

    docker导出镜像命令_docker save将容器保存为镜像导入导出命令介绍涉及的命令有export、import、save、loadsave示例dockersave-onginx.tarnginx:latest或dockersave>nginx.tarnginx:latest其中-o和>表示输出到文件,nginx.tar为目标文件,nginx:latest是源镜像名(name:tag),后面也可以是容器idload示例dockerload-inginx.tar或dockerload<n

    2025年9月22日
    7

发表回复

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

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