(10) ejb学习: Jpa的JTA事务和RESOURCE_LOCAL事务
一 事務的基本概念
? ?1 原子性 : 所有操作要么都成功,要么都失敗
? ?2 一致性 : 事務不能違反完整性約束(比如雖然事務還未提交,但仍然需要遵守約束規則,這些規則是事務提交之前而
? ? ? ? ? ? ? ? ? ? 非事務提交之后才能生效)
? ?3 隔離性 : 一個事務的效果,不能影響其它同時執行的事務
? ?4 持久性 : 一旦事務成功完成,則數據必須保證已經正確的持久化
二 JDBC事務和JTA事務對比
?1 ?JDBC事務只能支持一個數據庫(單數據源),而JTA可以支持分布式的事務(多數據源)
?2 JDBC事務,一般數據庫本身來執行提交或者回滾操作(單階段提交),所有數據庫都有它自己的事務管理器,管理執行的
? ? 日志,這些管理器只能處理自身的事務(稱為本地事務)
?3 而JTA不同,JTA要支持多個數據源,站在更高的角度上,提供“事務處理監視器(TPM)”來管理和協調這些數據源之間的事務
? ? 操作.它必須執行兩個階段的提交的(2PC)協議.
? ? 3.1 準備階段 : TPM向所有RM(資源管理器,即數據庫)確認狀態,是否可以提交或回滾。
? ? 3.2 提交階段 : TPM確認提交之后,向所有的RM發出提交指令(或回滾)
?4 TPM本身會維護事務日志,以保證持久性(災難恢復等)
三 事務類型 ; JTA 和RESOURCE_LOCAL
? 1 使用JAT來控制事務
? ? ?利用容器提供的JTA事務管理器來管理事務
? ?2 使用RESOURCE_LOCAL來控制事務
? ? ? 可以脫離容器
四 案例
?1 項目結構圖
Student.java : 學生實體類
StudentManager.java 學生管理接口類
StudentManagerImpl.java 學生管理實現類
JtaTest.java ?Junit測試類,
? ? ? ? ? ? ? ?測試1 :?testWithoutJta?沒有JTA時候的效果
?? ?? ? ??測試2 :?testJta? 使用JTA時候的效果
? ???? ? ? ? ??測試3 :?testLocal 測試使用?RESOURCE_LOCAL 的效果
persistence.xml : 配置RESOURCE_LOCAL和JTA的數據源
jndi.properties : 配置JNDI
client : 為JtaTest中testWithoutJta 和?testJta? 提供客戶端環境
? ? ? ? ? ? jar包有 : JBOSS_HOME/client/*.jar
RESOURCE_LOCAL 為JtaTest中testLocal 提供環境
? ? ? ? ? ?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 {/*** 沒有JTA測試* 每調用studentManager.addStudent("張三"+i)就是一個事物* 當i==5時候,拋出異常,因此有 張三0,張三1,張三2,張三3,張三4,張三5 這6個實體類被保存在數據庫中* **/@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測試* 與testWithoutJta代碼基本一樣,不同點在于開啟了JTA事物,studentManager.addStudent("張三"+i) (i=0,1,2,3,4,5)都在一個事物中* 發生throw new RuntimeException()后,事物回滾,因此沒有插入任何數據* **/@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(); //開啟事物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();}}/*** 測試本地容器事物* **/@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
? ? ? ? ? ? ? ? ??
總結
以上是生活随笔為你收集整理的(10) ejb学习: Jpa的JTA事务和RESOURCE_LOCAL事务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (9) ebj学习: Jpa的增删查改,
- 下一篇: (11) ejb学习: Jpa事务管理类