JamesGore
事务是用户定义的操作序列,是一个逻辑工作单元。事务存在的目的是保证系统的正确性,保证系统对应的数据资源,如数据库、文件系统,以受控的方式操作,所以事务本身具有4个限定属性:原子性、一致性、隔离性、持久性。
一、 局部事务与全局事务一个事务处理场景中,一般包含以下几个角色:
资源管理者:ResourceManger ,负责存储并管理系统数据资源的状态,如数据库服务器,JMS消息服务器等。
事务处理监视者:TransactionProcess Monitor,负责分布式事务场景中协调多个RM的事务处理。一般中间件或应用服务器担当此角色。
事务管理者:TransactionManager,可以认为是TP monitor的核心模块,直接负责RM事务处理,包括事务界定,事务上下文传递等功能。
应用程序:触发事务的边界点
事实上,并不是每个事务处理过程都包含这些角色,根据整个事务过程中涉及到资源管理者多少,可以分为局部事务与全局事务。这两类事务,具体的参与者不一样。
1. 全局事务如果整个事务处理过程中,包含多个RM,那么就需要引入TP Monitor来协调多个RM之间的事务处理。
应用程序提交事务请求,TPMonitor调配之后,由TM统一协调,TM将使用两阶段协议来协调多个RM之间的事务处理。
2. 局部事务如果当前事务中有一个资源管理者参与,那么当前事务就是局部事务。比如说一个系统只有一个数据源,或者有多个数据源,但每次事务只涉及到一个数据源。
局部事务中只涉及到一个RM,那TP Monitor就没有存在的必要,应用程序直接和RM打交道,通常情况下,RM都有内置的事务支持,如数据库的事务管理。局部事务,实践当中,更倾向使用内置事务支持,减少复杂度与事务开销。
二、 JAVA事务管理在程序开发中,我们关心的是通过相应的产品API获取事务资源,考虑在业务逻辑中界定事务边界,并不关心各供应商如何实现事务。JAVA平台提供了各种各样的事务管理API,应用于局部事务场景与全局事务场景。
1. 局部事务支持局部事务管理方式,不使用专门的事务管理API,而使用数据访问技术的API进行事务管理,局部事务随着数据访问技术的不同而异。从前面可知,局部事务RM都有内置事务支持,所以局部事务管理是基于数据访问技术所提供,应用程序与数据资源之间通信通道的API来管理事务,也就是说基于连接的API管理事务。
l JDBCJDBC是java平台数据访问最基础的API,基于java.sql.Connection,控制事务的提交与回滚。
Connection connection = ...
connnection.setAutoCommit(false)
...
connection.commit();或connection.rollback();
l Ibatis\Mybatismybatis是基于jdbc的封装,封装了jdbc模板代码,实现了实体与sql语句之间的映射。
SqlSession session = sqlSessionFractory.open(false);
...
session.commit();或session.rollback();
l Hibernate如果说mybatis是实体与sql之间的映射,那么hibernate是实体与表之间的映射。hibernate基于Session进行数据访问的事务管理(可以配置hibernate基于jdbc的局部事务管理,或者使用分布式事务管理)。
Session session = factory.open();
Transaction transaction =session.beginTransaction;
...
transaction.commit(); 或 transaction.rollback();
l JPAJPA是一个持久化规范,hiberante是其中的一种实现方式(也是事实上的标准),其它实现还有TopLink、OpenJPA。JPA基于EntityManage进行事务管理。
EntityManger em = ...
em.getTransaction().begin();
...
em.getTransaction().commit() 或 em.getTransaction().rollback();
l JMSJMS是基于javax.jmx.Session进行事务控制。
Session session = ...
...
session.commit(); 或 session.rollback();
局部事务管理常常涉及到一的一个问题是“连接”的传递,当在一个服务中包含多次数据访问时,数据访问层必须使用同一个“连接”,这是程序设计需要考虑的问题,否则无法地做到事务的原子性。
一般有两种思路解决这个问题,一个是参数传递,服务层开启连接(事务),传递给各个数据访问层;另一个是使用ThreadLocal,把“连接”绑定到线程上。
2. 全局事务支持Java平台上的分布式事务,主要通过JTA支持。JTA是java标准分布式事务接口规范,具体实现由相应的供应商实现,各j2ee应用服务器需要提供对JTA的支持。除了应用服务器支持外,还有其它独立的JTA实现产品,如JOTM、Atomikos、JBoss Transaction等。
JTA采用X/Open XA实现两阶段协议,X/OpenXA接口是双向的系统接口,在事务管理器及资源管理者之间
最近公司有需要,要找一个项目管理工具,网上看了redmine还不错,最终项目经理选择了它,让我把平台给搭建起来并熟悉其中的功能。搭建的过程中超过了我的预计还破费了点功夫,他是ruby语言。我也不懂,根据网上的一个安装教程来运行不是报这个错就是报那个错,关键也看不懂撒,郁闷! 这程序是卸了又装装了卸。没一次成功的,最后终于在一篇博客上给我试成功了,特此给有需要的童鞋们一个参考,免得走弯路,费时又费力。
安装文件 :railsinstaller-2.1.0.exe;redmine-2.1.3.zip;libmySQL.dll
下载地址: http://pan.baidu.com/share/link?shareid=189086&uk=201836219 密码:3645【网上都可以下载到的】
步骤:
1.安装 Ruby on Rails
双击railsinstaller-2.1.0.exe,一键搞定!
记得勾选上添加环境变量的选项。
2.解压 Redmine
解压redmine-2.1.3.zip 到d:\redmine
3.复制 libmysql.dll 文件
将libmysql.dll 文件,放到 Ruby 安装位置的 bin 目录下(D:\RailsInstaller\Ruby1.9.3\bin).
4.开始安装 Redmine
打开命令行跳转到redmine解压目录:
d:
cd D:\redmine\redmine-2.1.3
# 我们跳过了 ImageMagick 的安装
bundle install --without development test rmagick好,会提示安装成功,嗯,接下来要创建数据库。
5.创建一个 MySQL 数据库
使用Navicat(其他数据库管理工具也可以)创建一个可以访问的数据库。
这里以数据库 redmine,用户名密码为 redmine/ my_password 为例。
6.修改配置
复制一份 D:\redmine\redmine-2.1.3\config\database.yml.example 到D:\redmine\redmine-2.1.3\config\database.yml,然后打开它,开始编辑。
我们主要关注 production 这一节,下面是示例配置:
production:adapter: mysql2
database: redmine
host: localhost
username: redmine
password: my_password
encoding: utf8
注意: 1.上述信息要和你之前创建的数据库信息吻合,也就是能根据上述信息成功访问 MySQL 数据库。
2.纯数字的密码要用英文引号引起来。
3.adapter 改为使用 mysql2。
7.生成 Session 存储密钥
rake generate_secret_token
8.创建数据库结构,并导入默认数据
set RAILS_ENV=production
rake db:migraterake redmine:load_default_data
# 根据提示输入 zh 并回车
9.启动服务
进入D:\redmine\redmine-2.1.3\config 输入rails s 启动服务。成功画面如下:
或者ruby script/server -e production
10.登录
使用浏览器打开 http://localhost:3000/,如果一切正常,你应该可以看到 Redmine界面了。
管理员账户默认为 admin / admin。
进入系统之后修改语言为中文,在myaccount和setting里面可以修改。
ldr lr, =halt_loop @设置返回地址
ldr pc, =main @b指令和bl指令只能前后跳转32M的范围,所以这里使用向pc赋值的方法进行跳转
halt_loop:
b halt_loop
确实是将指针指向main函数,对于汇编调用C函数之前一定要配置lr,也就是链接寄存器,因为C函数执行完需要返回的,返回的时候pc指针会指向lr中的地址,此时就是halt_loop.当c函数执行完程序就返回到halt_loop指向的 b halt_loop,进行死循环。不知道你看汇编程序的时候有没有看到在程序的最后都会写类似这样的语句
stop:
b stop
就是让程序停在这,这个时候可以看各个寄存器的值,以便检查自己程序是否正确。如果是C函数比如用到printf("alkdjfkl");之类的。如果不让程序死循环,这种输出会瞬间消失,你也就不知道输没输出了。所以最后的死循环是很有作用的。