Mryqu's Notes


  • 首页

  • 搜索
close

事务管理器同步机制应用

时间: 2013-10-27   |   分类: Service+JavaEE     |   阅读: 395 字 ~2分钟
在我目前的项目中,缓存管理器需要根据事务提交状态对应用缓存进行管理。这里对其机制应用做一个小总结。 事务管理器 javax.transaction.TransactionManager接口定义一些方法以便应用服务器管理事务边界,比如获取与当前线程绑定的事务、对事务执行resume和suspend方法。 事务 javax.transaction.Transaction接口允许对目标事务对象执行相关的事务操作。在每个全局事务创建时,Transaction对象也对应的创建出来。 事务对象可以被用来做资源获取(resource enlistment)、同步器注册(synchronizationregistration)、事务结束(transaction completion)和状态查询(statusquery)操作。 事务同步机制 事务管理器通过javax.transaction.Synchronization接口支持一种同步机制。通过对当前事务的目标Transaction对象调用registerSynchronization方法,应用服务器为该事务注册一个Synchronization对象。 事务管理器在启动2PC事务提交过程时,回调Synchronization对象的beforeCompletion方法通知有关部分事务将要被提交;事务管理器在事务已经提交或回滚后,回调Synchronization对象的afterCompletion方法通知有关部分事务的结束状态。 应用一般很少使用beforeCompletion方法,afterCompletion方法使用比较多。在我目前的项目中,就是使用afterCompletion方法来通知缓存管理器对缓存进行更新操作。 实例代码 package com.yqu.transaction; import java.lang.reflect.Method; import javax.naming.InitialContext; import javax.transaction.RollbackException; import javax.transaction.Synchronization; import javax.transaction.SystemException; import javax.transaction.Transaction; import javax.transaction.TransactionManager; public class SynchronizationSample implements Synchronization { private static int wepsphereVer; private static final String WEBSPHERE_TM_FACTORY51 = "com.ibm.ws.Transaction.TransactionManagerFactory"; private static final String WEBSPHERE_TM_FACTORY50 = "com.ibm.ejs.jts.jta.TransactionManagerFactory"; private static final String WEBSPHERE_TM_FACTORY4 = "com.ibm.ejs.jts.jta.JTSXA"; private static final String WEBLOGIC_TM_OBJNAME = "javax.transaction.TransactionManager"; private static final String JBOSS_TM_OBJNAME = "java:/TransactionManager"; private static final String TOMCAT_TM_OBJNAME = "java:comp/env/TransactionManager"; private static final String WEBSPHERE_RECOG_CLASS = "com.
阅读全文 »

[Eclipse] 确认Eclipse是32/64bit的方法

时间: 2013-10-26   |   分类: Tool   Eclipse     |   阅读: 11 字 ~1分钟
两种方法: 打开Eclipse界面:Help -> About Eclipse -> Installation Details -> Configuration,若看到x86字样说明Eclipse是32bit的,若看到x86_64或x64字样则说明Eclipse是64bit的。 查看Eclipse安装目录下的eclipse.ini文件,如果launcher.library设置的值中写的是X86就说明Eclipse是32bit的,如果写的是x86_64或x64则说明Eclipse是64bit的。

[JPA] CascadeType.REMOVE与orphanRemoval的区别

时间: 2013-10-26   |   分类: db+nosql     |   阅读: 44 字 ~1分钟
Cascading Remove 将引用字段标注为CascadeType.REMOVE(或包含REMOVE的CascadeType.ALL)表明删除操作将应该自动级联到由该字段引用的实体对象(多个实体对象可以由集合字段引用): @Entity class Employee { : @OneToOne(cascade=CascadeType.REMOVE) private Address address; : } Orphan Removal JPA2额外支持一种更积极的删除级联模式,可以通过@OneToOne和@OneToMany注释的orphanRemoval元素设置: @Entity class Employee { : @OneToOne(orphanRemoval=true) private Address address; : } 区别 两个设置的区别在于关系断开的响应。 例如,将地址字段设置为null或另一个Address对象时,不同设置的结果是不同。 如果指定了 orphanRemoval = true,则断开关系的的Address实例将被自动删除。这对于清除没有所有者对象(例如Employee)引用的、不该存在的依赖对象(例如Address)很有用。 如果仅指定 cascade = CascadeType.REMOVE,则不会执行上述自动删除操作,因为断开关系不是删除操作。 参考 Deleting JPA Entity Objects

nohup命令笔记

时间: 2013-10-26   |   分类: Tool   Linux     |   阅读: 44 字 ~1分钟
Unix/Linux下一般比如想让某个程序在后台运行,很多都是使用 &在程序结尾来让程序自动运行。比如我们要运行mysql在后台: /usr/local/mysql/bin/mysqld_safe --user=mysql & 但是很多程序并不象mysqld一样做成守护进程,一般普通程序使用 &结尾在后台运行,如果终端关闭了,普通程序还是会被关闭。如果想要在退出帐户/关闭终端之后继续运行相应的普通进程。我们就可以使用nohup这个命令,nohup就是不挂起的意思(nohang up)。 nohup COMMAND [ARG]... nohup 命令运行由 Command参数和任何相关的 Arg参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加&到命令的尾部。 如果不将 nohup 命令的输出重定向,输出将附加到当前目录的 nohup.out 文件中。如果当前目录的 nohup.out文件不可写,输出重定向到 $HOME/nohup.out 文件中。如果没有文件能创建或打开以用于追加,那么 Command参数指定的命令不可调用。如果标准错误是一个终端,那么把指定的命令写给标准错误的所有输出作为标准输出重定向到相同的文件描述符。 nohup command > myout.file 2>&1 该命令返回下列出口值: 126:可以查找但不能调用 Command 参数指定的命令。 127:nohup 命令发生错误或不能查找由 Command 参数指定的命令。 其他:Command 参数指定命令的退出状态。 使用jobs查看任务。使用fg %n关闭。

切记:Java中long字面量以L结尾

时间: 2013-10-26   |   分类: Java     |   阅读: 25 字 ~1分钟
最近碰到一个问题,输入是int,要求按无符号整数使用。为了实现要求,升级成long然后与上0xffffffff,结果不正常。问了几个基友,都有点茫然。 问题出在0xffffffff上了,现在就操练一下。 将0xffffffff赋给一个long变量,它的值是多少? long n = 0xffffffff; System.out.println(Long.toHexString(n)); 结果是0xffffffffffffffff呦! ffffffffffffffff 将0x000000008fffffff赋给一个long变量,它的值是多少? long = 0x000000008fffffff; System.out.println(Long.toHexString(n)); 结果是0xffffffff8fffffff呦!!! ffffffff8fffffff int转换成long的规则是,一个负的int数,会自动扩展符号位,升级成负的long数的。 正确的用法是0xffffffffL,字面量表明是long类型,所以头32位才会全是0。 long = 0xffffffffL; System.out.println(Long.toHexString(n)); 输出结果: ffffffff

[C++] 重温函数隐藏和重写

时间: 2013-10-26   |   分类: C++     |   阅读: 758 字 ~4分钟
首先回顾一下C++的重载、隐藏和重写概念: 在相同作用域中,同名不同参的函数称为重载,这是c++多态的一种表现。对相同名字的成员函数,编译器可以根据传递的参数类型调用相应的成员函数。同名不同参的全局函数和类成员函数由于作用域不同,不是重载。不能通过函数返回值进行重载。像int和float这样不同的参数类型,可能会由于隐式转换隐患而无法通过编译。 当派生类中的成员函数/变量和基类中的成员函数/变量同名时,会隐藏基类的成员函数/变量,也就是指在派生类调用这个同名的成员函数/变量,调用的是派生类的成员函数/变量,而不是基类的那个成员函数/变量。可以通过类名::成员函数/变量去访问基类中同名的成员函数/变量。 派生类中的成员函数与基类的成员函数同名同参,就称为重写。当直接访问成员函数调用的是在派生类中重写的函数而不是从基类继承下来的成员函数,如果要访问从基类继承下来的成员函数也是通过类名::成员函数这种方式去调用基类的成员函数。 下面的小示例testOverride.cpp用于测试添加virtual与否对重写的影响: class BaseClass { public: BaseClass() { cout << "BaseClass() on " << this << endl; } BaseClass(const BaseClass&) { cout << "BaseClass(BaseClass) on " << this << endl; } virtual void vfun1() { cout << "BaseClass:vfun1() on " << this << endl; } virtual void vfun2() { cout << "BaseClass:vfun2() on " << this << endl; } void fun1() { cout << "BaseClass:fun1() on " << this << endl; } void fun2() { cout << "BaseClass:fun2() on " << this << endl; } virtual ~BaseClass() { cout << "~BaseClass() on " << this << endl; } }; class DerivedClass : public BaseClass { public: DerivedClass():name(new string("NULL")) { cout << "DerivedClass() on " << this << endl; } DerivedClass(const string& n):name(new string(n)) { cout << "DerivedClass(string) on " << this << endl; } void vfun1() { cout << "DerivedClass:vfun1() on " << this << endl; } void fun1() { cout << "DerivedClass:fun1() on " << this << endl; } ~DerivedClass() { delete name; cout << "~DerivedClass(): name has been deleted on " << this << endl; } private: void vfun2() { cout << "DerivedClass:vfun2() on " << this << endl; } void fun2() { cout << "DerivedClass:fun2() on " << this << endl; } private: string* name; }; int main() { cout << "=== test bo1 ===" << endl; BaseClass* bo1 = new BaseClass(); bo1->vfun1(); bo1->vfun2(); bo1->fun1(); bo1->fun2(); delete bo1; cout << "=== test do1 ===" << endl; DerivedClass* do1 = new DerivedClass(); do1->vfun1(); // error: 'virtual void DerivedClass::vfun2()' is private // within this context // do1->vfun2(); do1->fun1(); // error: 'void DerivedClass::fun2()' is private // within this context // do1->fun2(); delete do1; cout << "=== test bo2 ===" << endl; BaseClass* bo2 = new DerivedClass("123"); bo2->vfun1(); bo2->vfun2(); bo2->fun1(); bo2->fun2(); delete bo2; return 0; } vfun2和fun2在BaseClass类中是public访问权限,而在DerivedClass类中是private访问权限。
阅读全文 »

[Eclipse] Find the override method implementation in subclasses

时间: 2013-10-26   |   分类: Tool   Eclipse     |   阅读: 34 字 ~1分钟
已知当前对象为org.apache.hadoop.hdfs.client.HdfsDataInputStream实例,调用其祖宗抽象类java.io.InputStream的publicint read(byte b[], int off, int len) throwsIOException方法,究竟最后使用的是那个类的实现呢? 由如上类继承图可知,应该从对象类往上依次查找方法实现:HdfsDataInputStream、FSDataInputStream、……。工作很繁琐,挑战眼力! 一个快捷的方式就是进入java.io.InputStream类,选中read(byte b[], int off, intlen) 方法,按住CTRL键后点击鼠标左键,这样会出现一个菜单: 选择OpenImplementation菜单,输入HdfsDataInputStream、FSDataInputStream、……,可以更轻松的找到重写该方法的子类。 最终可知使用的是java.io.DataInputStream类中的实现: public final int read(byte b[], int off, int len) throws IOException { return in.read(b, off, len); }

学习十二要素应用宣言

时间: 2013-10-25   |   分类: Tech     |   阅读: 275 字 ~2分钟
Heroku是业内知名的云应用平台,从对外提供服务以来,他们已经有上百万应用的托管和运营经验。大概在去年,创始人Adam Wiggins根据这些经验,发布了一个“十二要素应用宣言(The Twelve-Factor App)”。 简介 如今,软件通常会作为一种服务来交付,它们被称为网络应用程序,或软件即服务(SaaS)。12-Factor为构建如下的SaaS应用提供了方法论: 使用标准化流程自动配置,从而使新的开发者花费最少的学习成本加入这个项目。 和操作系统之间尽可能的划清界限,在各个系统中提供最大的可移植性。 适合部署在现代的云计算平台,从而在服务器和系统管理方面节省资源。 将开发环境和生产环境的差异降至最低,并使用持续交付实施敏捷开发。 可以在工具、架构和开发流程不发生明显变化的前提下实现扩展。 这套理论适用于任意语言和后端服务(数据库、消息队列、缓存等)开发的应用程序。 背景 本文的贡献者者参与过数以百计的应用程序的开发和部署,并通过Heroku平台间接见证了数十万应用程序的开发,运作以及扩展的过程。 本文综合了我们关于 SaaS应用几乎所有的经验和智慧,是开发此类应用的理想实践标准,并特别关注于应用程序如何保持良性成长,开发者之间如何进行有效的代码协作,以及如何避免软件污染。 我们的初衷是分享在现代软件开发过程中发现的一些系统性问题,并加深对这些问题的认识。我们提供了讨论这些问题时所需的共享词汇,同时使用相关术语给出一套针对这些问题的广义解决方案。本文格式的灵感来自于Martin Fowler 的书籍:Patterns of Enterprise Application Architecture,Refactoring。 读者应该是哪些人? 任何SaaS应用的开发人员。部署和管理此类应用的运维工程师。 12-Factors I. 基准代码 一份基准代码,多份部署 12-Factor应用通常会使用版本控制系统加以管理,如Git、Mercurial、Subversion。一份用来跟踪代码所有修订版本的数据库被称作_代码库_(coderepository, code repo, repo)。 在类似 SVN这样的集中式版本控制系统中,_基准代码_就是指控制系统中的这一份代码库;而在Git那样的分布式版本控制系统中,_基准代码_则是指最上游的那份代码库。 基准代码和应用之间总是保持一一对应的关系: 一旦有多个基准代码,就不能称为一个应用,而是一个分布式系统。分布式系统中的每一个组件都是一个应用,每一个应用可以分别使用12-Factor进行开发。 多个应用共享一份基准代码是有悖于12-Factor原则的。解决方案是将共享的代码拆分为独立的类库,然后使用依赖管理策略去加载它们。 尽管每个应用只对应一份基准代码,但可以同时存在多份部署。每份_部署_相当于运行了一个应用的实例。通常会有一个生产环境,一个或多个预发布环境。此外,每个开发人员都会在自己本地环境运行一个应用实例,这些都相当于一份部署。 所有部署的基准代码相同,但每份部署可以使用其不同的版本。比如,开发人员可能有一些提交还没有同步至预发布环境;预发布环境也有一些提交没有同步至生产环境。但它们都共享一份基准代码,我们就认为它们只是相同应用的不同部署而已。 II. 依赖 显式声明依赖关系 大多数编程语言都会提供一个打包系统,用来为各个类库提供打包服务,就像Perl的CPAN或是Ruby的Rubygems。通过打包系统安装的类库可以是系统级的(称之为 “sitepackages”),或仅供某个应用程序使用,部署在相应的目录中(称之为 “vendoring” 或 “bunding”)。 **12-Factor规则下的应用程序不会隐式依赖系统级的类库。**它一定通过_依赖清单_,确切地声明所有依赖项。此外,在运行过程中通过_依赖隔离_工具来确保程序不会调用系统中存在但清单中未声明的依赖项。这一做法会统一应用到生产和开发环境。 例如,Ruby的Gem Bundler使用Gemfile 作为依赖项声明清单,使用bundle exec 来进行依赖隔离。Python中则可分别使用两种工具 – Pip用作依赖声明,Virtualenv用作依赖隔离。甚至C语言也有类似工具,Autoconf用作依赖声明,静态链接库用作依赖隔离。无论用什么工具,依赖声明和依赖隔离必须一起使用,否则无法满足12-Factor规范。 显式声明依赖的优点之一是为新进开发者简化了环境配置流程。新进开发者可以检出应用程序的基准代码,安装编程语言环境和它对应的依赖管理工具,只需通过一个_构建命令_来安装所有的依赖项,即可开始工作。例如,Ruby/Bundler下使用bundle install ,而Clojure/Leiningen则是lein deps。 12-Factor应用同样不会隐式依赖某些系统工具,如ImageMagick或是curl 。即使这些工具存在于几乎所有系统,但终究无法保证所有未来的系统都能支持应用顺利运行,或是能够和应用兼容。如果应用必须使用到某些系统工具,那么这些工具应该被包含在应用之中。 III. 配置 在环境中存储配置 通常,应用的_配置_在不同部署(预发布、生产环境、开发环境等等)间会有很大差异。这其中包括: 数据库,Memcached,以及其他后端服务的配置 第三方服务的证书,如 Amazon S3、Twitter等 每份部署特有的配置,如域名等 有些应用在代码中使用常量保存配置,这与12-Factor所要求的代码和配置严格分离显然大相径庭。配置文件在各部署间存在大幅差异,代码却完全一致。 判断一个应用是否正确地将配置排除在代码之外,一个简单的方法是看该应用的基准代码是否可以立刻开源,而不用担心会暴露任何敏感的信息。 需要指出的是,这里定义的"配置"并不包括应用的内部配置,比如Rails的config/routes.
阅读全文 »

[C++] 重温析构函数

时间: 2013-10-25   |   分类: C++     |   阅读: 466 字 ~3分钟
创建一个C++对象时,一般先调用父类构造函数,再调用自己的构造函数;而在销毁一个C++对象时,一般先调用自己的析构函数,再调用父类的析构函数。我用如下testDestructor.cpp进行测试。 class BaseClass { public: BaseClass() { cout << "BaseClass() on " << this << endl; } ~BaseClass() { cout << "~BaseClass() on " << this << endl; } }; class DerivedClass : public BaseClass { public: DerivedClass():name(new string("NULL")) { cout << "DerivedClass() on " << this << endl; } DerivedClass(const string& n):name(new string(n)) { cout << "DerivedClass(string) on " << this << endl; } ~DerivedClass() { delete name; cout << "~DerivedClass(): name has been deleted on " << this << endl; } private: string* name; }; int main() { cout << "=== test bo1 ===" << endl; BaseClass* bo1 = new BaseClass(); delete bo1; cout << "=== test do1 ===" << endl; DerivedClass* do1 = new DerivedClass(); delete do1; cout << "=== test bo2 ===" << endl; BaseClass* bo2 = new DerivedClass("123"); delete bo2; cout << "=== test bo3 ===" << endl; BaseClass bo3 = DerivedClass("321"); return 0; } 输出结果如下:
阅读全文 »

[HBase] HBase Shell交互实践

时间: 2013-10-25   |   分类: BigData     |   阅读: 1560 字 ~8分钟
HBase Shell是对HBase的脚本接口,是一个JRuby REPL(Read-Eval-PrintLoop,“读取-求值-输出”循环),可以通过脚本访问所有HBase客户端API。 单列族练习 创建表friends $ hbase shell hbase(main):001:0> list TABLE customer 1 row(s) in 0.2050 seconds => ["customer", "student"] hbase(main):002:0> create 'friends', 'd' 0 row(s) in 1.3350 seconds => Hbase::Table - friends hbase(main):003:0> list TABLE customer friends 2 row(s) in 0.0060 seconds => ["customer", "friends", "student"] 获得表friends的描述说明 hbase(main):004:0> describe 'friends' Table friends is ENABLED friends COLUMN FAMILIES DESCRIPTION {NAME => 'd', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCO PE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => 'FO REVER', KEEP_DELETED_CELLS => 'FALSE', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'} 1 row(s) in 0.
阅读全文 »
50 51 52 53 54 55 56 57 58

Programmer & Architect

662 日志
27 分类
1472 标签
RSS 订阅
GitHub Twitter FB Page
© 2009 - 2023 Mryqu's Notes
Powered by - Hugo v0.120.4
Theme by - NexT
0%