EJB3.0(四)JPA 分布式事务处理

JPA:全称java persistence API jpa作为j2ee的基础规范之一,也是目前作为比较流行ORM框架之一。不仅仅作为一种通用的标准ORM解决方案,也是企业级开发分布式事务的一种选择。

JTA:全称java transaction API
。可以在多个组件或者应用之间进行事务处理,相比JDBC来讲支持更多的数据源。

Ejb3.0
对于分布式事务也有支持,常常和EntityManager一起使用。下面是针对多个数据源的事务管理的代码实现以及在调试过程中的一些调式日志。

环境

jboss-5.0.0.GA  jdk 1.6

MyEclipse

Version:10.0

Buildid: 10.0-20111028

Code

EJB bean

实体配置

Person

package com.cfl.jpa;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Person implements Serializable{
	@Id
	@GeneratedValue
	private int id;

	private String age;
	private String height;

	public String getAge() {
		return age;
	}
	public void setAge(String age) {
		this.age = age;
	}
	public String getHeight() {
		return height;
	}
	public void setHeight(String height) {
		this.height = height;
	}

}

Persistent.xml

JPA 配置文件,配置多个数据源的文件配置

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">

	<persistence-unit name="test1" transaction-type="JTA">
		<!-- mysql数据源 -->
  		<jta-data-source>java:/MySqlDS1</jta-data-source>
  		<!-- 实体类 -->
  		<class>com.cfl.jpa.User</class>
  		<exclude-unlisted-classes>true</exclude-unlisted-classes>
  		<!--  <jta-data-source>java:/MyOracleDS</jta-data-source> -->
  		<properties>
  			<!-- 数据库方言 -->
  		  	 <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
  		 <!--  	<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/> -->
			<!-- 自动创建 -->
			<property name="hibernate.hbm2ddl.auto" value="create" />
			<!-- 显示sql语句 -->
			<property name="hibernate.show_sql" value="true" />

  		</properties>
	</persistence-unit>
		<persistence-unit name="test2" transaction-type="JTA">
  		<jta-data-source>java:/MySqlDS2</jta-data-source>
  		<class>com.cfl.jpa.Person</class>
  		<exclude-unlisted-classes>true</exclude-unlisted-classes>
  		<!--  <jta-data-source>java:/MyOracleDS</jta-data-source> -->
  		<properties>
  		  	 <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
  		 <!--  	<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/> -->
			<property name="hibernate.hbm2ddl.auto" value="create" />
			<property name="hibernate.show_sql" value="true" />
  		</properties>
	</persistence-unit>

</persistence>

EntityManager

这个不同数据源的实体管理器需求配置,默认情况只会更新一个数据源。

package com.cfl.jpa;

import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless(name="UM")
@Remote
public class UserManagerImpl implements UserManager {
	/*
	 * 如果只有一个unitName就无需书写这个,如果有两个unitName就需要
	 * 来指定哪个unitName的名称了
	 */
	@PersistenceContext(unitName="test1")
	private EntityManager em1;
	@PersistenceContext(unitName="test2")
	private EntityManager em2;

	public void addUser() {
		User user=new User();
		user.setAge("23");

		em1.persist(user);

		Person p=new Person();
		p.setAge("24");
		p.setHeight("1.7");

		em2.persist(p);
		//如果抛出异常则来自两个数据源的保存操作都会回滚,这就是跨域的事务处理
		//throw new RuntimeException("回滚事务exception");
		//System.out.print("u & p 保存成功!");
	}

}

在jboss的数据源配置

需要注意的是数据源的名称和对应连接到数据库的url。

<?xml version="1.0" encoding="UTF-8"?>

<!-- $Id: mysql-ds.xml 41017 2006-02-07 14:26:14Z acoliver $ -->
<!--  Datasource config for MySQL using 3.0.9 available from:
http://www.mysql.com/downloads/api-jdbc-stable.html
-->

<datasources>
  <local-tx-datasource>
    <jndi-name>MySqlDS1</jndi-name>
    <connection-url>jdbc:mysql://localhost:3306/MyUser</connection-url>
    <driver-class>com.mysql.jdbc.Driver</driver-class>
    <user-name>cfl</user-name>
    <password>123456</password>
    <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
    <metadata>
       <type-mapping>mySQL</type-mapping>
    </metadata>
  </local-tx-datasource>

    <local-tx-datasource>
    <jndi-name>MySqlDS2</jndi-name>
    <connection-url>jdbc:mysql://localhost:3306/MyPerson</connection-url>
    <driver-class>com.mysql.jdbc.Driver</driver-class>
    <user-name>cfl</user-name>
    <password>123456</password>
    <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
    <metadata>
       <type-mapping>mySQL</type-mapping>
    </metadata>
  </local-tx-datasource>
</datasources>

源代码下载:http://download.csdn.net/detail/chenfanglincfl/8206309

DebugLog

(javax.transaction.SystemException: java.lang.Throwable:

Unabled to enlist resource。。。

这个错误大致意思无法获得的资源

解决方案:把JBoss_Home/server/default/deploy下的mysql-ds.xml修改为mysql-xa-ds.xml

[com.arjuna.ats.internal.jta.transaction.arjunacore.lastResource.disallow]Adding multiple last resources is disallowed.

这个错误是无法配置多个数据员支持。也就是JTA在访问一个数据源是没有任何问题,但是在配置两个数据源时就出现了问题。

解决方案:

在/server/default/conf文件夹中jbossjta-properties.xml文件里    <propertiesdepends="arjuna" name="jta">下面增加子节点<propertyname="com.arjuna.ats.jta.allowMultipleLastResources"value="true"/>

Incorrect columnspecifier for column ‘addressId‘

这个错误也是比较常见的,是因为在配置自增长主键时,配置了字符串的主键,将主键配置为int或者配置为uuid的生存策略即可。

总结

JPA这里还有涉及到类似hibernate的四种状态,以及这些实体状态之间是如何来切换、EntityManager管理容器的工作原理后面再继续学习和交流。

时间: 2024-10-10 15:50:12

EJB3.0(四)JPA 分布式事务处理的相关文章

Eclipse + Jboss AS 7.1 创建 EJB3.0之JPA工程

0. EJB3.0 与 JPA 0 1. 环境预备 1 2. 配置开发环境 2 3. 工程描述 3 4. 步骤 4 5. 在MySQL中创建数据库表 5 6. 新建 EJB Project 6 7. 创建JPA实体 7 Eclipse + Jboss AS 7.1 创建 EJB3.0之JPA工程 0. EJB3.0 与 JPA EJB3.0是一份规范,该规范由不同的部分组成: 第一部分为session bean和message-driven bean定义了新的编程模型,以及部署规则等等: 第二部

itoo中为什么要用EJB3.0分布式框架

一说到EJB,总是有一种感觉就是EJB已经过时了,或者是在项目中,EJB太笨重了,使用过程中很多的功能都没有体现出来,而且EJB还会影响性能,但是在ITOO中为什么还要用EJB分布式框架呢? ITOO的技术框架结构图如下所示: 从这个图中可以看出,业务逻辑层使用EJB容器进行管理的,我刚开始接触到时候,我也很好奇为什么要用EJB分布式,而没有用webservice或者是现在比较火的阿里巴巴的dubbo+zookeeper呢.现在我就来解释以下为什么要选用企业级的ejb3.0. 第一:EJB3.0

EJB3.0

由于EJB2.0的复杂性,在Spring和Hibernate[1]  等轻量级框架出现后,大量的用户转向应用轻量级框架.在大家的呼声中, EJB 期待已久的EJB3.0规范终于发布了.在本文中将对新的规范进行一个概要性的介绍,包括新增的元数据支持,EJBQL的修改,实体Bean模型访问bean上下文的新方法和运行时环境等等.作者还讨论了EJB在未来要作出的调整以及EJB3.0与其他开发规范之间的关系. 开始 无论如何由于EJB的复杂性使之在J2EE架构中的表现一直不是很好.EJB大概是J2EE架

EJB3.0快速入门

1.首先介绍运行环境及相关的配置: EJB的运行环境: JAVAEE应用服务器包含Web容器和EJB容器,EJB3.0应用需要运行在EJB容器里. Tomcat目前只是Web容器,它不能运行EJB应用. Jboss作为最常用EJB容器,其自身所带Web服务器部分就是直接使用Tomcat(Jboss的默认端口也为:8080). 相关配置: 1.配置classpath:%JDK安装目录%/lib/dt.jar和tools.jar 2.JDK版本需要1.5以上. 3.为Jboss设置Jboss_HOM

EJB3.0中的session bean以及MDB解析

大型业务系统面临的主要问题就是高并发性和事务访问,客户端的数量与服务器端的分布式对象数量存在一定程度的正比关系,客户端数量越多,服务器端分布式对象也就越多,如何解决这种高并发的问题也就成了企业级架构首先要解决的问题.EJB作为一种服务器端分布式组件,为我们提供了应对策略. EJB提供了两种管理大量分布式对象的策略:实例池化和激活.下面分别对EJB组件模型中的三种模型进行一些分析. 第一种:无状态的会话Bean(Stateless session bean) Stateless session b

POJO应用框架:Spring与EJB3.0的比较

英文原文地址:http://www.onjava.com/pub/a/onjava/2005/06/29/spring-ejb3.html中文地址:http://www.matrix.org.cn/resource/article/43/43718_Spring_EJB.html关键词: Spring EJB 艾伯特.爱因斯坦曾经说过:"一切都应该尽可能地简单,但是不能更简单."确实如此,简化一门理论的基本假设,使我们可以专注于真正关键的地方,这正是一直以来对科学真理的追求.企业软件开

日均百万PV架构第四弹(分布式监控)

应该能更早出的第四弹,被虚拟机错误搅乱,迟迟没有上线,不得已将所有 节点用puppet完成上线,稍后整理第五弹(非你不可自动化)也即将上线 : ) zabbix简介    zabbix是基于Php的开源监控软件    基于多重数据采集 SNMP , Agent , Ping , Port    多重告警通知 Mail , Jabber , SMS    可以完成多种操作平台甚至于设备(route,switch,io)的监控工作    易于定制重用(模板机制,函数),甚至于二次开发    告警及时

EJB3.0与Spring

总的来看Spring+Hibernate与JPA很相似,它们都是基于pojo的持久化. Hibernate Session和JPA Entity Manager基本上等价,但是要记住他们的两个重要区别. Hibernate session是一个实体缓存也是一个ORM引擎的接口. 而JPA中这两个概念是分开的.Persistence context作为缓存而entity manager则作为ORM引擎的接口. 当然还有显而易见的区别,Spring+Hibernate偏向使用XML配置映射,而JPA

.NET简谈事务、分布式事务处理

在本人的 " .NET简谈事务本质论"一文中我们从整体上了解了事务模型,在我们脑子里能有一个全局的事务处理结构,消除对数据库事务的依赖理解,重新认识事务编程模型. 今天这篇文章我们将使用.NET C#来进行事务性编程,从浅显.简单的本地事务开始,也就是我们用的最多的ADO.NET事务处理,然后我们逐渐扩大事务处理范围,包括对分布式事务处理的使用,多线程事务处理的使用. 数据库事务处理 数据库事务处理我们基本都很熟悉了,begin Transaction --end Transactio