我在glassfish中部署了一个war文件。我们有一个Singleton bean,我们有1个同步方法。
@TransactionAttribute (TransactionAttributeType.REQUIRED)
public synchronized void do()
{
...
}
但是,我注意到在调用方法之前已启动事务。在调用者获取bean类的监视器上的锁之后,如何启动事务?
谢谢。
更新:我们只是尝试使用一个只能由一个线程一次调用的bean方法。我们不希望任何其他线程调用此方法,直到前一个线程完全完成它。我创建了另一个线程,我想到了使用单例bean:synchronized method in stateless session bean not working as expected in glassfish
更新:在做了一些阅读之后,似乎我可以创建自己的事务UserTransaction。这会得到支持吗?没关系。我收到此错误消息:
Only session beans with bean-managed transactions can obtain UserTransaction
答案 0 :(得分:1)
我认为一种方法是通过将对方法的调用包装到另一个bean中来将同步移出bean(YourBean将是bean类的接口):
public class WrapperBeanImpl implements WrapperBean {
private YourBean yb;
private final Object lock;
@Resource
private SessionContext ctx;
@PostConstruct
public void init() {
yb = ctx.getBusinessObject(YourBean.class);
}
@TransactionAttribute(TransactionAttributeType.NEVER)
public void synchronizedDo() {
synchronized(lock) {
yb.do();
}
}
}
(从http://www.javahelp.info/2009/11/01/using-transactionattribute-in-submethods-on-same-ejb3-beans/略微修改的示例)
当然,这并没有真正阻止任何人直接绕过这种额外的同步调用do()方法,尽管这可能不是问题。您还可以选择将同步保留在bean中作为额外的保护措施。
答案 1 :(得分:0)
只需在类级别使用@ConcurrencyManagementType(CONTAINER)
,容器将保持同步。并使用没有synchronized
指令的methond。