JTA事务
环境介绍
整合前
| 系统A | 系统B |
框架 | B/S | C/S |
服务器 | tomcat5.5 | glassfish-v2ur2 |
展现层 | webwork2.2.6(JSP+ftl+applet) | swing |
连接层 | spring2.0.7 | 无 |
数据库访问 | hibernate3.2.5 | JDBC |
数据库 | Sqlserver2000 | oracle9i |
整合后
框架 | C/S+S/B |
服务器 | glassfish-v2ur2 |
展现层 | webwork2.2.6(JSP+ftl+applet)+ swing |
连接层 | spring2.0.7 |
数据库访问 | hibernate3.2.5+ JDBC |
数据库 | oracle9i |
应用场景:
系统A调用系统B所暴露的service
下面的伪代码:
1. Class A{
2. Public static Void main(String[] args){
3. aMethod();
4. Bservice bService=new BServeiceImpl();
5. bService. bMethod ();
6. }
7. Public static void aMethod(){
8. //todo insert or update database(“insert into table --------==”)
9. }
10. }
A系统和B系统的数据库目前共用一个,但是以后随着业务的发展又可能用不同的数据库
那么在调用的时候如何做到事务一致呢?
解决方案
针对以上的要求有下面两种思考:
一、同一数据库:
1. 客户数据库操作与我们的服务使用同一个数据库连接。然后编程处理事务。存在两种方式:一种是把客户的连接传给我们,另一种则是把我们的连接传给客户。第一种方式对我们的影响太大,所以最后决定采用后一种方式:从hibernate session中获取connection然后传递给客户。接下来查看一下HibernateTemplate的execute()方法,思路就很简单了:获取定义的sessionFactory-->创建一个新的session并打开-->将session与当前线程绑定-->给客户代码返回connection-->打开事务-->客户使用我们传递的connection进行数据库操作-->我们不带声明事务的服务操作-->提交事务-->解除绑定。
实际要注意的地方是:1、将session与当前线程绑定使用的TransactionSynchronizationManager.bindResource()方法,这样在HibernateTemplate里才能找到session;
2、我们的服务一定要把声明式事务彻底干掉,否则会有commit;
3、我们服务调用完毕后一定要flush session,否则客户代码不会感知数据库里的数据变化。
最终解决:使用了spring里常用的模板和回调。
详细代码请访问:http://www.blogjava.net/RongHao/archive/2007/10/09/151411.html
二、不同数据库
采用JTA事务
期待的方式:
- Class A{
2. Public static Void main(String[] args){
3. Try{
4. //JTA事务开始
5. aMethod();
6. Bservice bService=new BServeiceImpl();
7. bService. bMethod ();
8. //JTA事务提交
9. }catch{
10. //JTA事务回滚
}
下面将详细的介绍从glassfish数据源配置、spring数据源配置、JNDI数据源调用等配置
笔者默认用户已经安装了glassfish和oracle(安装过程可以google相关文章)
glassfish数据源配置
http://localhost:4848/ 进入glassfish的管理页面