EJB(四)JPA 分布式事务处理
JPA:全稱java persistence API jpa作為j2ee的基礎(chǔ)規(guī)范之一,也是目前作為比較流行ORM框架之一。不僅僅作為一種通用的標(biāo)準(zhǔn)ORM解決方案,也是企業(yè)級(jí)開發(fā)分布式事務(wù)的一種選擇。
?
JTA:全稱java transaction API。可以在多個(gè)組件或者應(yīng)用之間進(jìn)行事務(wù)處理,相比JDBC來講支持更多的數(shù)據(jù)源。
?
Ejb3.0對于分布式事務(wù)也有支持,常常和EntityManager一起使用。下面是針對多個(gè)數(shù)據(jù)源的事務(wù)管理的代碼實(shí)現(xiàn)以及在調(diào)試過程中的一些調(diào)式日志。
?
環(huán)境
? ? ? ? ? jboss-5.0.0.GA? jdk 1.6?
?MyEclipse
?Version:10.0
?Buildid: 10.0-20111028
Code
EJB bean
實(shí)體配置
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@GeneratedValueprivate 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 配置文件,配置多個(gè)數(shù)據(jù)源的文件配置
<?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/persistencehttp://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"><persistence-unit name="test1" transaction-type="JTA"><!-- mysql數(shù)據(jù)源 --><jta-data-source>java:/MySqlDS1</jta-data-source> <!-- 實(shí)體類 --><class>com.cfl.jpa.User</class><exclude-unlisted-classes>true</exclude-unlisted-classes><!-- <jta-data-source>java:/MyOracleDS</jta-data-source> --><properties><!-- 數(shù)據(jù)庫方言 --><property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" /> <!-- <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/> --><!-- 自動(dòng)創(chuàng)建 --><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?
? ? ? ?這個(gè)不同數(shù)據(jù)源的實(shí)體管理器需求配置,默認(rèn)情況只會(huì)更新一個(gè)數(shù)據(jù)源。
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 {/** 如果只有一個(gè)unitName就無需書寫這個(gè),如果有兩個(gè)unitName就需要* 來指定哪個(gè)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);//如果拋出異常則來自兩個(gè)數(shù)據(jù)源的保存操作都會(huì)回滾,這就是跨域的事務(wù)處理//throw new RuntimeException("回滾事務(wù)exception");//System.out.print("u & p 保存成功!");}}
在jboss的數(shù)據(jù)源配置
? ? ? ? ?需要注意的是數(shù)據(jù)源的名稱和對應(yīng)連接到數(shù)據(jù)庫的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。。。
這個(gè)錯(cuò)誤大致意思無法獲得的資源
解決方案:把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.?
這個(gè)錯(cuò)誤是無法配置多個(gè)數(shù)據(jù)員支持。也就是JTA在訪問一個(gè)數(shù)據(jù)源是沒有任何問題,但是在配置兩個(gè)數(shù)據(jù)源時(shí)就出現(xiàn)了問題。
解決方案:
在/server/default/conf文件夾中jbossjta-properties.xml文件里????<propertiesdepends="arjuna" name="jta">下面增加子節(jié)點(diǎn)<propertyname="com.arjuna.ats.jta.allowMultipleLastResources"value="true"/>
Incorrect columnspecifier for column 'addressId'
這個(gè)錯(cuò)誤也是比較常見的,是因?yàn)樵谂渲米栽鲩L主鍵時(shí),配置了字符串的主鍵,將主鍵配置為int或者配置為uuid的生存策略即可。
?
總結(jié)
JPA這里還有涉及到類似hibernate的四種狀態(tài),以及這些實(shí)體狀態(tài)之間是如何來切換、EntityManager管理容器的工作原理后面再繼續(xù)學(xué)習(xí)和交流。
轉(zhuǎn)載于:https://www.cnblogs.com/guziming/p/4232664.html
總結(jié)
以上是生活随笔為你收集整理的EJB(四)JPA 分布式事务处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多线程(二)线程控制
- 下一篇: 百度地图 IOS版开发经验分享