事务管理服务
最有用的容器服务可能就是事务管理服务,当应用出现失败或异常时,它保证了数据库的完整性。最常见的事务是定义在session bean 的方法上,方法中所有的数据库操作只有在方法正常退出时才会提交,如果方法抛出未捕获的异
常,事务管理将回滚所有的变更。
@TransactionAttribute 注释用作定义一个需要事务的方法。它可以有以下参数:
1.REQUIRED:方法在一个事务中执行,如果调用的方法已经在一个事务中,则使用该事务,否则将创建一
个新的事务。
2.MANDATORY:如果运行于事务中的客户调用了该方法,方法在客户的事务中执行。如果客户没有关联到
事务中,容器就会抛出TransactionRequiredException。如果企业bean 方法必须用客户事务则采用Mandatory 属性。
3.REQUIRESNEW:方法将在一个新的事务中执行,如果调用的方法已经在一个事务中,则暂停旧的事务。在
调用结束后恢复旧的事务。
4.SUPPORTS:如果方法在一个事务中被调用,则使用该事务,否则不使用事务。
5.NOT_SUPPORTED:如果方法在一个事务中被调用,容器会在调用之前中止该事务。在调用结束后,容器
会恢复客户事务。如果客户没有关联到一个事务中,容器不会在运行入该方法前启动一个新的事务。用
NotSupported 属性标识不需要事务的方法。因为事务会带来更高的性能支出,所以这个属性可以提高性能。
6.Never:如果在一个事务中调用该方法,容器会抛出RemoteException。如果客户没有关联到一个事务中,
容器不会在运行入该方法前启动一个新的事务。
如果没有指定参数,@TransactionAttribute 注释使用REQUIRED 作为默认参数。
下面的代码展示了事务管理的开发:
TransactionDAOBean.java
package com.zhaosoft.session;
import java.util.List;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import com.zhaosoft.bean.Product;
import com.zhaosoft.exception.TransException;
@Stateless
@Remote( { TransactionDAO.class })
public class TransactionDAOBean implements TransactionDAO {
@PersistenceContext
protected EntityManager em;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void insertProduct(String name, Float price, boolean error) {
try {
for (int i = 0; i < 3; i++) {
Product product = new Product(name + i, price * (i + 1));
em.persist(product);
}
if (error) {
new Float("kkk"); // 制造一个例外
}
} catch (Exception e) {
throw new RuntimeException("应用抛出运行时例外,为了使事务回滚,外部不要用try/catch包围");
}
}
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void ModifyProductName(String newname, boolean error)
throws Exception {
Query query = em.createQuery("select p from Product p");
List result = query.getResultList();
if (result != null) {
for (int i = 0; i < result.size(); i++) {
Product product = (Product) result.get(i);
product.setName(newname + i);
em.merge(product);
}
if (error && result.size() > 0)
throw new TransException("抛出应用例外");
}
}
}
上面定义了两个需要事务的方法,容器在运行这两个方法时将会创建一个事务,方法里的所有数据库操作都在此
事务中运行,当这两个方法正常退出时,事务将会提交,所有更改都会同步到数据库中。如果方法抛出
RuntimeException 例外或ApplicationException 例外,事务将会回滚。方法ModifyProductName 中使用的
TransException 类是一个自定义ApplicationException 例外。代码如下:
TransException.java
package
com.zhaosoft.exception;
public
class
TransException
extends
Exception {
public
TransException(String message) {
super
(message);
}
}
@ApplicationException 注释定义了在例外抛出时将回滚事务。
下面是TransactionDAOBean 的接口
TransactionDAO.java
package
com.zhaosoft.session;
public
interface
TransactionDAO {
public
void
insertProduct(String name, Float price,
boolean
error);
public
void
ModifyProductName(String newname,
boolean
error)
throws
Exception ;
}
下面是TransactionDAOBean 使用的实体Bean
Product.java
package com.zhaosoft.bean;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "Products")
public class Product implements Serializable {
private int hashCode = Integer.MIN_VALUE;
private Integer productid;
private String name;
private Float price;
public Product() {
}
public Product(String name, Float price) {
this.name = name;
this.price = price;
}
@Id
@GeneratedValue
public Integer getProductid() {
return productid;
}
public void setProductid(Integer productid) {
this.productid = productid;
}
@Column(name = "ProductName", nullable = false, length = 50)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(nullable = false)
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
public boolean equals(Object obj) {
if (null == obj)
return false;
if (!(obj instanceof Product))
return false;
else {
Product mObj = (Product) obj;
if (null == this.getProductid() || null == mObj.getProductid())
return false;
else
return (this.getProductid().equals(mObj.getProductid()));
}
}
public int hashCode() {
if (Integer.MIN_VALUE == this.hashCode) {
if (null == this.getProductid())
return super.hashCode();
else {
String hashStr = this.getClass().getName() + ":"
+ this.getProductid().hashCode();
this.hashCode = hashStr.hashCode();
}
}
return this.hashCode;
}
}
下面是Session Bean 的JSP 客户端代码:
<%@
page
contentType
=
"text/html; charset=GBK"
%>
<%@
page
import
=
"com.zhaosoft.session.TransactionDAO,
javax.naming.*,
java.util.*"
%>
<%
Properties props =
new
Properties();
props.setProperty(
"java.naming.factory.initial"
,
"org.jnp.interfaces.NamingContextFactory"
);
props.setProperty(
"java.naming.provider.url"
,
"localhost:1099"
);
props.setProperty(
"java.naming.factory.url.pkgs"
,
"org.jboss.naming"
);
try
{
InitialContext ctx =
new
InitialContext(props);
TransactionDAO transactiondao = (TransactionDAO)
ctx.lookup(
"TransactionDAOBean/remote"
);
//transactiondao.insertProduct("
电脑
", new Float("1200"),false);
transactiondao.ModifyProductName(
"
数码相机
"
,
true
);
out.println(
"
执行完成
"
);
}
catch
(Exception e) {
out.println(e.getMessage());
}
%>
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"
>
<
persistence-unit
name
=
"EJB17PU"
transaction-type
=
"JTA"
>
<
jta-data-source
>
java:/zhaosoft
</
jta-data-source
>
<
properties
>
<
property
name
=
"hibernate.hbm2ddl.auto"
value
=
"create-drop"
/>
</
properties
>
</
persistence-unit
>
</
persistence
>
我喜欢的
浏览器 |
我喜欢的
文化礼品 |
我喜欢的
ISP网站 |
我喜欢的
网站 |
FireFox 2.0
|
100部奥斯卡影片
|
时代互联
|
博告网
|
|
|
时代互联10元换空间
|
加入博告网日进斗金不是梦!
|
聚合到我的好诶网博告网 提供的广告 |