最有用的容器服务可能就是事务管理服务,当应用出现失败或异常时,它保证了数据库的完整性。你可以简单地将为一个
POJO
方法申明它的事务属性
。这样容器就可以在合适的上下文中运行这个方法。最常见的事务是定义在
session bean
的方法上
,方法中所有的数据库操作只有在方法正常退出时才会提交,如果方法抛出未捕获的异常,事务管理将回滚所有的变更。
@TransactionAttribute
用作定义一个需要事务的方法。它可以有以下参数:
1.REQUIRED
:方法在一个事务中执行,如果调用的方法已经在一个事务中,则使用该事务,否则将创建一个新的事务。
2.MANDATORY
:如果运行于事务中的客户调用了该方法,方法在客户的事务中执行。如果客户没有关联到事务中,容器就会抛出
TransactionRequiredException
。如果企业
bean
方法必须用客户事务则采用
Mandatory
属性。
3.REQUIRESNEW:
方法将在一个新的事务中执行,如果调用的方法已经在一个事务中,则暂停旧的事务。在调用结束后恢复旧的事务。
4.SUPPORTS:
如果方法在一个事务中被调用,则使用该事务,否则不使用事务。
5.NOT_SUPPORTED
:如果方法在一个事务中被调用,容器会在调用之前中止该事务。在调用结束后,容器会恢复客户事务。如果客户没有关联到一个事务中,容器不会在运行入该方法前启动一个新的事务。用
NotSupported
属性标识不需要事务的方法。因为事务会带来更高的性能支出,所以这个属性可以提高性能。
6.Never
:如果在一个事务中调用该方法,容器会抛出
RemoteException
。如果客户没有关联到一个事务中,容器不会在运行入该方法前启动一个新的事务。
如果没有指定参数,
@TransactionAttribute
使用
REQUIRED
作为默认参数。
例:
public class
TransactionDAOBean
implements
TransactionDAO {
。。。。
@TransactionAttribute(TransactionAttributeType.
REQUIRED
)
public void
insertProduct(String name, Float price,
boolean
error) {
try
{
Product product =
new
Product(name,price);
em
.persist(product);
//
制造一个例外,但这个Exception是app exception,无法导致回滚
//
因此在catch里抛出一个RuntimeException来回滚
if
(error)
new
Float(
"kkk"
);
}
catch
(Exception e) {
throw new
RuntimeException (
"
抛出
RuntimeException
,
导致事务回滚"
);
}
}
@TransactionAttribute(TransactionAttributeType.
REQUIRED
)
public void
insertProduct2(String name, Float price,
boolean
error) {
Product product =
new
Product(name,price);
em
.persist(product);
if
(error)
//
抛出一个app exception,该exception是自定义的、能够导致回滚的exception
//
见下面的TransException class
throw new
TransException (
"
抛出应用例外"
);
}
}
@SuppressWarnings
(
"serial"
)
@ApplicationException(rollback=true)
public class
TransException
extends
Exception {
public
TransException (String message) {
super
(message);
}
}
@ApplicationException
定义了在例外抛出时将回滚事务
上述只是简单的事务知识点,以后会补充