(10) ejb学习: Jpa的JTA事务和RESOURCE_LOCAL事务
一 事務(wù)的基本概念
? ?1 原子性 : 所有操作要么都成功,要么都失敗
? ?2 一致性 : 事務(wù)不能違反完整性約束(比如雖然事務(wù)還未提交,但仍然需要遵守約束規(guī)則,這些規(guī)則是事務(wù)提交之前而
? ? ? ? ? ? ? ? ? ? 非事務(wù)提交之后才能生效)
? ?3 隔離性 : 一個(gè)事務(wù)的效果,不能影響其它同時(shí)執(zhí)行的事務(wù)
? ?4 持久性 : 一旦事務(wù)成功完成,則數(shù)據(jù)必須保證已經(jīng)正確的持久化
二 JDBC事務(wù)和JTA事務(wù)對(duì)比
?1 ?JDBC事務(wù)只能支持一個(gè)數(shù)據(jù)庫(kù)(單數(shù)據(jù)源),而JTA可以支持分布式的事務(wù)(多數(shù)據(jù)源)
?2 JDBC事務(wù),一般數(shù)據(jù)庫(kù)本身來(lái)執(zhí)行提交或者回滾操作(單階段提交),所有數(shù)據(jù)庫(kù)都有它自己的事務(wù)管理器,管理執(zhí)行的
? ? 日志,這些管理器只能處理自身的事務(wù)(稱為本地事務(wù))
?3 而JTA不同,JTA要支持多個(gè)數(shù)據(jù)源,站在更高的角度上,提供“事務(wù)處理監(jiān)視器(TPM)”來(lái)管理和協(xié)調(diào)這些數(shù)據(jù)源之間的事務(wù)
? ? 操作.它必須執(zhí)行兩個(gè)階段的提交的(2PC)協(xié)議.
? ? 3.1 準(zhǔn)備階段 : TPM向所有RM(資源管理器,即數(shù)據(jù)庫(kù))確認(rèn)狀態(tài),是否可以提交或回滾。
? ? 3.2 提交階段 : TPM確認(rèn)提交之后,向所有的RM發(fā)出提交指令(或回滾)
?4 TPM本身會(huì)維護(hù)事務(wù)日志,以保證持久性(災(zāi)難恢復(fù)等)
三 事務(wù)類型 ; JTA 和RESOURCE_LOCAL
? 1 使用JAT來(lái)控制事務(wù)
? ? ?利用容器提供的JTA事務(wù)管理器來(lái)管理事務(wù)
? ?2 使用RESOURCE_LOCAL來(lái)控制事務(wù)
? ? ? 可以脫離容器
四 案例
?1 項(xiàng)目結(jié)構(gòu)圖
Student.java : 學(xué)生實(shí)體類
StudentManager.java 學(xué)生管理接口類
StudentManagerImpl.java 學(xué)生管理實(shí)現(xiàn)類
JtaTest.java ?Junit測(cè)試類,
? ? ? ? ? ? ? ?測(cè)試1 :?testWithoutJta?沒(méi)有JTA時(shí)候的效果
?? ?? ? ??測(cè)試2 :?testJta? 使用JTA時(shí)候的效果
? ???? ? ? ? ??測(cè)試3 :?testLocal 測(cè)試使用?RESOURCE_LOCAL 的效果
persistence.xml : 配置RESOURCE_LOCAL和JTA的數(shù)據(jù)源
jndi.properties : 配置JNDI
client : 為JtaTest中testWithoutJta 和?testJta? 提供客戶端環(huán)境
? ? ? ? ? ? jar包有 : JBOSS_HOME/client/*.jar
RESOURCE_LOCAL 為JtaTest中testLocal 提供環(huán)境
? ? ? ? ? ?jar包有?: JBOSS_HOME/server/default/lib/*.jar
? ? ? ? ? ? ? ? ? ? ? ? ?JBOSS_HOME/lib/*.jar
五 代碼
Student.java
StudentManager.java
package leaning;public interface StudentManager {public void addStudent(String name); }
StudentManagerImpl.java
package leaning;import javax.ejb.Remote; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext;@Stateless(name="studentManager") @Remote public class StudentManagerImpl implements StudentManager {@PersistenceContext(unitName="EjbLession11_JTA")private EntityManager em;public void addStudent(String name) {Student s = new Student();s.setName(name);em.persist(s);}}
JtaTest.java
package test;import static org.junit.Assert.*;import javax.naming.InitialContext; import javax.naming.NamingException; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.transaction.SystemException; import javax.transaction.UserTransaction;import leaning.Student; import leaning.StudentManager;import org.junit.Test;public class JtaTest {/*** 沒(méi)有JTA測(cè)試* 每調(diào)用studentManager.addStudent("張三"+i)就是一個(gè)事物* 當(dāng)i==5時(shí)候,拋出異常,因此有 張三0,張三1,張三2,張三3,張三4,張三5 這6個(gè)實(shí)體類被保存在數(shù)據(jù)庫(kù)中* **/@Testpublic void testWithoutJta() {InitialContext context;try {context = new InitialContext();StudentManager studentManager = (StudentManager)context.lookup("studentManager/remote");for(int i = 0 ; i < 10 ; i++){studentManager.addStudent("張三"+i);if(i==5){throw new RuntimeException();}}} catch (NamingException e) {e.printStackTrace();}}/*** JTA測(cè)試* 與testWithoutJta代碼基本一樣,不同點(diǎn)在于開(kāi)啟了JTA事物,studentManager.addStudent("張三"+i) (i=0,1,2,3,4,5)都在一個(gè)事物中* 發(fā)生throw new RuntimeException()后,事物回滾,因此沒(méi)有插入任何數(shù)據(jù)* **/@Testpublic void testJta() {InitialContext context;try {context = new InitialContext();//JTA事物管理接口UserTransaction utx = (UserTransaction)context.lookup("UserTransaction");StudentManager studentManager = (StudentManager)context.lookup("studentManager/remote");try{utx.begin(); //開(kāi)啟事物for(int i = 0 ; i < 10 ; i++){studentManager.addStudent("張三"+i);if(i==5){throw new RuntimeException();}}utx.commit(); //提交事物}catch(Exception e){try {utx.rollback(); //回滾} catch (Exception e1 ) {e1.printStackTrace();} e.printStackTrace();}} catch (NamingException e) {e.printStackTrace();}}/*** 測(cè)試本地容器事物* **/@Testpublic void testLocal() {EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("EjbLession11_RESOURCE_LOCAL");// 取 persistence.xml中 persistence-unit name="EjbLession11_RESOURCE_LOCAL" EntityManager em = entityManagerFactory.createEntityManager();try{em.getTransaction().begin();Student student = new Student();student.setName("李四");em.persist(student);em.getTransaction().commit();}catch(Exception e){em.getTransaction().rollback();e.printStackTrace();}} }
persistence.xml
<?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"><!-- 采集JTA事物 --><persistence-unit name="EjbLession11_JTA" transaction-type="JTA"><jta-data-source>java:/MySqlDS</jta-data-source><properties><property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /><property name="hibernate.hbm2ddl.auto" value="update"/></properties></persistence-unit><!-- 采用RESOURCE_LOCAL事物 --><persistence-unit name="EjbLession11_RESOURCE_LOCAL" transaction-type="RESOURCE_LOCAL"><provider>org.hibernate.ejb.HibernatePersistence</provider><properties><property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /><property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/ejb" /><property name="hibernate.connection.username" value="root" /><property name="hibernate.connection.password" value="root" /><property name="hibernate.show_sql" value="true"/><property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /><property name="hibernate.hbm2ddl.auto" value="update"/></properties></persistence-unit></persistence>
jndi.properties
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.provider.url=localhost java.naming.factory.url.pkgs=org.jboss.naming\:org.jnp.interfaces
? ? ? ? ? ? ? ? ??
總結(jié)
以上是生活随笔為你收集整理的(10) ejb学习: Jpa的JTA事务和RESOURCE_LOCAL事务的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: (9) ebj学习: Jpa的增删查改,
- 下一篇: (11) ejb学习: Jpa事务管理类