(12) ejb学习: JPA的传播属性

一 为什么需要传播属性


service调用图


如上图所示 ,  service2 可能被单独调用,也有可能被service1调用 ,也有可能在其它service中调用, 因此不能使用 UserTransaction utx方式将 

service2放入service1中 , 此刻就需要用到事务传播了,假设用service1用了required,会在service1中会创建一个事务,并将该事务传到service2中,

因此service1,service2都在同一个事务中了.


二 传播属性特性以及管理

 1 Not Supportd - 不支持,如果当前有事务上下文,将挂起当前的事务

 2 Support - 支持 , 如果有事务,将使用事务,如果没有事务,将不使用事务.

 3 Required - 需要 , 如果当前有事务上下文,将使用当前的上下文的事务,

          如果没有,则创建新的事务

 4 Required New - 需要新的事务,如果当前有事务上下文,将挂起当前的事务,

     并创建新的事务去执行任务,执行完成之后,在恢复到原来的事务.

 5 Mandatory - 当前必须要有事务上下文,如果当前没有事务,将抛出异常

 6 Nerver - 当前必须不能有事务上下文,如果有事务,将抛出异常.


三 ejb中使用传播属性示例

1 项目结构

 

Student.java : 学生实体类

StudentManager.java 学生管理接口类

StudentManagerImpl.java 学生管理实现类

StudentManagerClient.java  Junit测试类,

               测试1 : testAddStudent1  没有事务,增加学生失败效果

               测试2 : testAddStudent2 有事务,增加用户成功

persistence.xml : 配置JTA的数据源

jndi.properties : 配置JNDI

client : 为JtaTest中testWithoutJta 和 testJta  提供客户端环境

            jar包有 : JBOSS_HOME/client/*.jar

2 代码

Student.java

package leaning;

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

@Entity
public class Student {

	@Id
	@GeneratedValue
	private int id;

	private String name;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}
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.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;



/**
 * 事务传播属性为 Supports
 * **/
@Stateless(name="studentManager")
@Remote
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
public class StudentManagerImpl implements StudentManager {
	
	@PersistenceContext(unitName="propagation_unit")
	private EntityManager em;

	
	// persist 需要事务支持
	public void addStudent(String name) {
		Student s = new Student();
		s.setName(name);
		em.persist(s);
		
	}

}

StudentManagerClient.java

package test;

import static org.junit.Assert.*;

import javax.naming.InitialContext;
import javax.transaction.UserTransaction;

import leaning.StudentManager;

import org.junit.Test;

public class StudentManagerClient {

	
	/**
	 * 没有事务,增加用户失败
	 * */
	@Test
	public void testAddStudent1() {
		try{
			InitialContext context = new InitialContext();
			StudentManager studentManager = (StudentManager)context.lookup("studentManager/remote");
			// 服务器端使用了事务传播特性为SUPPORTS即支持事务,如果没有事务,将不使用事务
			// 现在客户端没有事务,但服务端执行更新又必须要有事务支持,所以本次操作将抛出异常,无法执行
			studentManager.addStudent("张三");
		}catch(Exception e){
			
			e.printStackTrace();
		}
		
		
		
	}
	
	/**
	 * 有事务,增加用户成功
	 * */
	@Test
	public void testAddStudent2() {
		try{
			InitialContext context = new InitialContext();
			StudentManager studentManager = (StudentManager)context.lookup("studentManager/remote");
			//JTA事物管理接口
			UserTransaction utx = (UserTransaction)context.lookup("UserTransaction");
			try{
				utx.begin(); //开启事物
				  studentManager.addStudent("张三");
				utx.commit(); //提交事物
			}catch(Exception e){
				utx.rollback();
				e.printStackTrace();
			}
			
			
		}catch(Exception e){
			
			e.printStackTrace();
		}
		
		
		
	}

}
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


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/persistence
    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
    
	 <!-- 采集JTA事物 -->
	<persistence-unit name="propagation_unit" 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>
  
</persistence>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值