`
weilJava
  • 浏览: 70165 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类
最新评论

grails+atomikos 多事务管理

阅读更多

一、问题:

    使用的grails开发项目当配置多个数据源时,非默认数据源的事务会失效

二、探索:

    网上找到spring同样存在这样的问题,必须使用atomikos

三、atomikos插件

    grails官网上有atomikos插件,但是好多年不用了,并且这个插件是在grails1.3.5基础上开发的,并且依赖的jar也下载不下来了,更不要谈安装插件了

    最后尝试将插件代码下载下来,重新修改,修改需要注意几个问题

    1、grails版本要改为你项目用的版本

    2、BuildConfig文件中dependencies引用到的jar包都下载不下来,需要自己手动下载相应的jar包,注意版本问题,并且注释掉dependencies里面的所有compile

    3、修改文件AtomikosGrailsPlugin.groovy中

System.setProperty 'com.grails.atomikos.icatch.service',UserTransactionServiceFactory.name

    的“grails”去掉

 

上面的三个问题修改后,就可以打自己的atomikos的插件了,见附件

 

四、grails+atomikos

     在项目中安装自己打好的插件,开始配置了

     1、BuildConfig.groovy

plugins {
    ...
    compile ':atomikos:1.0'
}

     2、Config.groovy

grails.plugin.atomikos.uts = [
        'com.atomikos.icatch.console_file_name'        : 'tm.out',
        'com.atomikos.icatch.log_base_name'            : 'tmlog',
        'com.atomikos.icatch.tm_unique_name'           : 'tsTransactionManager',
        'com.atomikos.icatch.console_log_level'        : 'ERROR',
        'com.atomikos.icatch.log_base_dir'             : 'target/atomikos',
        'com.atomikos.icatch.output_dir'               : 'target/atomikos',
        'com.atomikos.icatch.force_shutdown_on_vm_exit': 'true']

     3、数据源配置DataSource.groovy

development {
         //默认数据源
        dataSource {
            pooled = true
            url = 'jdbc:mysql://localhost:3309/main
            driverClassName = 'com.mysql.jdbc.Driver'
            properties {
                username = "root"
                password = "root"
                maxIdle = "30"
                maxWait = "10000"
                maxActive = -1
            }
            xaConfig = [
                    driverClassName: 'com.mysql.jdbc.jdbc2.optional.MysqlXADataSource',
                    driverProperties: [
                            URL: 'jdbc:mysql://localhost:3309/main',
                            user: 'root',
                            password: 'root',
                            pinGlobalTxToPhysicalConnection: "true",
                            autoReconnect: true,
                            autoReconnectForConnectionPools: true,
                            autoReconnectForPools: true],
                    minPoolSize: 1,
                    maxPoolSize: 50
            ]
        }


        //非默认数据源
        dataSource_ts {
            pooled = true
            url = 'jdbc:mysql://localhost:3309/ts?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull'
            driverClassName = 'com.mysql.jdbc.Driver'
            properties {
                username = "root"
                password = "root"
                maxIdle = "30"
                maxWait = "10000"
                maxActive = -1
            }
            xaConfig = [
                    driverClassName: 'com.mysql.jdbc.jdbc2.optional.MysqlXADataSource',
                    driverProperties: [
                            URL: 'jdbc:mysql://localhost:3309/ts?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull',
                            user: 'root',
                            password: 'root',
                            pinGlobalTxToPhysicalConnection: "true",
                            autoReconnect: true,
                            autoReconnectForConnectionPools: true,
                            autoReconnectForPools: true],
                    minPoolSize: 1,
                    maxPoolSize: 50
            ]
        }
    }

    pinGlobalTxToPhysicalConnection: "true"其中这个一定要配置,否则会有问题,请参见http://www.atomikos.com/Documentation/KnownProblems#MySQL_XA_bug

    4、测试代码

          1)分别创建两个类MainTask使用默认数据源,Task使用ts

          2)Service代码

class TaskService {
    //默认为true,当改为false抛任何异常,数据都会保存
    static transactional = true;

    def saveTask() {
//        Task t = Task.get(92l);//更新
        Task t = new Task();
        t.taskName = t.taskName + "testdhw_noclick"
        t.save();
        saveOpenTask()
    }

    Object saveOpenTask() {
        OpenTask ot = new OpenTask();
        ot.taskName = ot.taskName + "open_task_test"
        ot.save();
        throw new RuntimeException("save task fail!");
    }
}

 

验证事务已经起作用了,当 transactional =false,即使最后抛出RunTimeException异常,数据同样会保存

 

五、另外一个问题

    多数据源事务失效问题引起的另外一个“分页查询”问题也同时得到了解决

grails分页的确很方便,但是当你所查询的类不是默认数据源时,悲剧了,你必须将得transactional =false才能正常查询,(ps:曾经啊,,,曾经就让这个问题悄悄溜过去了)

    控制类代码如下

class TaskController {
    TaskService taskService;
    def list = {
        def resultMap = [:];
        try {
            PagedResultList pageList = taskService.queryTaskByCondition(params);
            //Task为非默认数据源,在不使用插件的情况下,在事务开启状态时,控制类里获取总数方法会报connection is close!!!
            if (pageList.getTotalCount() == 0) {
                resultMap << ['total': 0];
                resultMap << ['rows': []];
            } else {
                resultMap << ['total': pageList.getTotalCount()];
                resultMap << ['rows': pageList.list];
            }
        } catch (Exception e) {
            log.error("查询任务列表出错:" + e.getMessage(), e);
            resultMap << ['total': 0];
            resultMap << ['rows': []];
        }
        render(resultMap as JSON);
    }
}

   service代码如下

class TaskService {
    
    static transactional = true;

    PagedResultList queryTaskByCondition(GrailsParameterMap params) {
        def currPage = params.page ? Integer.valueOf(params.page) : 1;
        def pageSize = params.rows ? Integer.valueOf(params.rows) : 10;
        def offset = (currPage - 1) * pageSize;
        params.max = pageSize;
        params.offset = offset;

        def searchParam = {
            order('updateTime', "desc");
            order('id', "desc");
        }
        def criteria = Task.createCriteria();
        PagedResultList pageResult = criteria.list(params, searchParam);
        return pageResult;
    }
}

 

六、相关查阅资料

1、spring存在同样的问题解决方案

http://loftor.com/archives/spring-mybatis-tomcat-jta.html

2、插件依赖的jar下载,注意版本注意版本注意版本(重要的事说三遍)

http://mvnrepository.com/artifact/com.atomikos

3、官方插件文档

http://grails-plugins.github.io/grails-atomikos/docs/manual/guide/2%20Getting%20Started.html

4、github插件源码

http://grails-plugins.github.io/grails-atomikos/

5、jtapropertie介绍

http://www.atomikos.com/Documentation/JtaProperties

 

 

 

 

分享到:
评论
1 楼 weilJava 2015-08-31  
增加另外一种简单处理事务的代码
    def saveTask() {
        Task t = Task.get(148l);
        Task.withTransaction { status ->
            if (!commonService.save()) {
                status.setRollbackOnly()
            }
        }
    }

    def save() {
        Task t = new Task();
        t.taskName = t.taskName + "testdhw_noclick"
        t.save();
        throw new RuntimeException("save task fail!");
        return true;
    }

相关推荐

    Grails+ZK文档

    Grails+ZK文档,Grails+ZK文档,Grails+ZK文档,Grails+ZK文档

    Grails+groovy 完整参考手册.7z

    通过阅读《Grails+groovy 完整参考手册.docx》,你可以更深入地了解这两个技术,包括它们的原理、最佳实践以及实际应用中的案例。无论你是初学者还是有经验的开发者,这份手册都将是你学习和提升技能的宝贵资源。

    grails+Xfire webservice

    grails+Xfire webservice

    Grails+Apache構築手順

    Grails+Apache構築手順 apache配置手順 tomcat配置手順

    Grails + Spring Security 权限控制

    本文将深入探讨如何在Grails框架中集成Spring Security,实现高效且灵活的权限管理。 Grails是一个基于Groovy语言的全栈式、敏捷的Web应用框架,它简化了Java开发流程,提供了丰富的插件生态系统。Spring Security...

    Grails+快速开发+Web+应用程序.pdf

    ### Grails快速开发Web应用程序知识点解析 #### 一、Grails框架概述 - **定义**:Grails是一个基于Groovy语言构建的开源Model-View-Controller (MVC) Web开发框架。它旨在简化Web应用程序的开发流程,提高开发效率...

    The+Definitive+Guide+to+Grails+Second+Edition

    - **性能优化**:探讨如何通过缓存、异步处理和资源管理等策略来提高 Grails 应用的性能。 - **部署和运维**:了解 Grails 应用在生产环境下的部署流程,包括配置管理、日志记录和监控策略。 ### 实战应用 本书...

    grails_blog:Grails + MongoDB 博客

    综上所述,"grails_blog:Grails + MongoDB 博客" 主要涵盖了 Grails 框架的使用,Groovy 语言的应用,以及 MongoDB 的集成与数据管理。对于想要学习全栈开发,特别是 Grails 和 NoSQL 数据库的人来说,这是一个很好...

    todo:Grails + angularjs

    在这个项目中,可能Grails作为主后端框架处理业务逻辑和数据管理,Vert.x则作为辅助工具,负责处理高并发和实时通信,而AngularJS则在前端构建用户交互界面。 Grails是一个基于Groovy语言的开源Web应用框架,它简化...

    TOO-115:东正教组织ProecectologíasOrientadas a Objetos,desarrollado en Grails + Oracle

    工具115 Proyecto para la MateriaTecnologíasOrientadas a Objetos,desarrollado en Grails + Oracle

    grails login

    在Grails中实现用户登录功能是构建任何Web应用的基础,它确保了数据的安全性和用户权限的管理。本示例将详细解释如何在Grails中创建一个用户登录系统,特别是对于管理员用户的特定权限控制。 **1. 配置环境** 首先...

    grails 中文文档+grails-fckeditor-0.9.5.zip插件

    3. 扩展性:FCKEditor插件可以与其他Grails插件(如文件上传插件)配合使用,提供更强大的功能,如图片管理和多媒体资源管理。 4. 版本兼容:虽然grails-fckeditor-0.9.5是较旧的版本,但理解其工作原理有助于我们...

    Grails 入门指南+示例源码

    《Grails 入门指南》是一本专门为初学者设计的教程,旨在帮助新手快速掌握Grails框架的基础知识和实际应用。Grails是一个基于Groovy语言的全栈式、开源的Web应用框架,它以简化开发流程和提高生产力为目标,特别适合...

    学生管理系统课程设计(grails)

    在学生管理系统课程设计中,Grails可以用来快速构建包括用户管理、课程管理、成绩管理等多个模块的功能。首先,我们需要创建数据库模型,这通常涉及到定义领域类(Domain Classes),这些类对应于数据库中的表,并...

    Grails Grails Grails

    它提供了CRUD操作,以及事务管理和动态查询。 3. **插件系统**:Grails 插件是一组可重用的功能模块,可以快速增强应用程序的功能,如Spring Security、Asset Pipeline等。 4. **命令行工具**:Grails 提供强大的...

    grails中文入门简介

    Grails还支持Ant和Maven,这意味着可以利用这两种构建工具的生态来管理Grails项目。 对象关系映射(GORM)是Grails框架中的一个重要组成部分,它为Groovy语言提供了对象持久化的支持。GORM支持基本的CRUD操作,并且...

    Eclipse下搭建Grails项目

    在Eclipse中,Grails项目的结构和管理将得到很好的支持,包括源代码编辑、构建、测试和调试。 注意,尽管Eclipse对Grails的支持相比IntelliJ IDEA和NetBeans可能稍显不足,但通过Groovy Eclipse插件的配置,开发者...

    Grails权威指南 Grails权威指南

    9. **国际化与本地化**:Grails内置了i18n支持,允许开发者轻松处理多语言环境,提高应用的全球适用性。 10. **持续集成与部署**:Grails与常见的CI/CD工具如Jenkins、GitLab CI/CD等良好集成,方便自动化部署和...

Global site tag (gtag.js) - Google Analytics