从方法a()调用方法b()时是否启动新事务? 或者这只是来自对象的方法调用而且注释不起作用? 如果是这样,该交易如何开始?
@Stateless
public class TestBean {
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public void a() {
b();
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void b() {
}
}
答案 0 :(得分:4)
您可以使用TransactionSynchronizationRegistry
资源查询当前交易状态,轻松检查。这是我在Wildfly 8.1上尝试的一个例子:
1 - 将TransactionSynchronizationRegistry注入资源:
@Resource
TransactionSynchronizationRegistry txReg;
2 - 查询当前tranaaction状态并返回人类可读字符串的小助手:
private String getTXStatus()
{
int txStatus = this.txReg.getTransactionStatus();
switch (txStatus)
{
case Status.STATUS_ACTIVE:
return "STATUS_ACTIVE";
case Status.STATUS_COMMITTED:
return "STATUS_COMMITTED";
case Status.STATUS_COMMITTING:
return "STATUS_COMMITTING";
case Status.STATUS_MARKED_ROLLBACK:
return "STATUS_MARKED_ROLLBACK";
case Status.STATUS_NO_TRANSACTION:
return "STATUS_NO_TRANSACTION";
case Status.STATUS_PREPARED:
return "STATUS_PREPARED";
case Status.STATUS_PREPARING:
return "STATUS_PREPARING";
case Status.STATUS_ROLLEDBACK:
return "STATUS_ROLLEDBACK";
case Status.STATUS_ROLLING_BACK:
return "STATUS_ROLLING_BACK";
case Status.STATUS_UNKNOWN:
return "STATUS_UNKNOWN";
default:
return "Unknown(" + txStatus + ")";
}
3 - 现在您可以通过一些快速而肮脏的日志记录来检测您的业务方法(并且永远不要将System.out.println()
放入高效的EJB代码中!
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public void a()
{
System.out.println("+++ a()");
System.out.println("TX status is " + getTXStatus());
b();
System.out.println("TX status is " + getTXStatus());
System.out.println("--- a()");
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void b()
{
System.out.println("+++ b()");
System.out.println("TX status is " + getTXStatus());
System.out.println("--- b()");
}
4 - 现在我们可以从某个客户端调用a()
然后b()
:
String beanName = "ejb:EJB3/MOD3//SagMalWas!de.treufuss.ejb3project.client.HelloWorldRemote";
HelloWorldBIF bif = HelloWorldBIF.class.cast(jndiContext.lookup(beanName));
bif.a();
bif.b();
在服务器控制台中产生以下输出:
12:58:33,123 INFO [stdout] (EJB default - 3) +++ a()
12:58:33,123 INFO [stdout] (EJB default - 3) TX status is STATUS_NO_TRANSACTION
12:58:33,123 INFO [stdout] (EJB default - 3) +++ b()
12:58:33,123 INFO [stdout] (EJB default - 3) TX status is STATUS_NO_TRANSACTION
12:58:33,123 INFO [stdout] (EJB default - 3) --- b()
12:58:33,124 INFO [stdout] (EJB default - 3) TX status is STATUS_NO_TRANSACTION
12:58:33,124 INFO [stdout] (EJB default - 3) --- a()
12:58:33,127 INFO [stdout] (EJB default - 4) +++ b()
12:58:33,128 INFO [stdout] (EJB default - 4) TX status is STATUS_ACTIVE
12:58:33,128 INFO [stdout] (EJB default - 4) --- b()
证明从b()
a
没有启动任何事务
<强>附录强>
您可以通过EJB上下文中的Bean业务接口调用b()
方法来强制创建新事务。要做到这一点......
1 - 将EJB上下文注入资源
@Resource
private SessionContext ctx;
2 - 通过业务接口调用b()
方法:
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public void a()
{
System.out.println("+++ a()");
System.out.println("TX status is " + getTXStatus());
// Direct invocation is treated as POJMC (plain old java method call
b();
// Indirect invocation via EJB context
HelloWorldLocal thisBean = ctx.getBusinessObject(HelloWorldLocal.class);
thisBean.b();
System.out.println("TX status is " + getTXStatus());
System.out.println("--- a()");
}
答案 1 :(得分:2)
不会启动任何交易。这被视为内部方法,并与当前事务相关联。由于您a()
方法声明了NOT_SUPPORTED
事务属性,因此在调用方法a()
和b()
期间不会创建任何事务。当客户端调用该方法时,会考虑事务属性,因此如果某个组件将调用testBean.b()
,则无论是否存在事务,都将创建新事务。