![](/img/trans.png)
[英]Difference between @Transactional and @TransactionAttribute
[英]Wildfly - @TransactionAttribute -
在我的項目中使用Wildfly 10,java 8,mysql,camel和hibernate
methodKO持久化實體orderEntity(“ko”),調用methodOK並進入異常; methodOK持久化實體orderEntity(“ok”)
盡管在methodKO中有異常,我想在db中找到orderEntity(“ok”),所以我用@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)注釋了methodOK,但這不起作用
這里有配置文件的詳細信息:
獨立-全ha.xml:
<datasources>
<xa-datasource jndi-name="java:jboss/datasources/myDS" pool-name="myDS" enabled="true" use-ccm="true">
....
</datasources>
persistence.xml中:
<persistence-unit name="camel" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/myDS</jta-data-source>
....
為myBean:
@Stateless
public class MyBean {
@Inject
OrderDAO orderDAO;
private void methodKO() throws Exception {
orderDAO.create(new orderEntity("ko"));
methodOK();
throw new Exception("err");
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
private void methodOK() {
orderDAO.create(new orderEntity("ok"));
}
}
根據EJB 3.1:
事務屬性是與以下每種方法關聯的值:
a)bean的業務接口的方法
b)通過bean類無接口視圖公開的方法
這意味着私有方法上的任何Transactional注釋都是無用的。
我會將這兩種方法定義為公共方法:
@Stateless
public class MyBean {
@Inject
OrderDAO orderDAO;
public void methodKO() throws Exception {
orderDAO.create(new orderEntity("ko"));
methodOK();
throw new Exception("err");
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void methodOK() {
orderDAO.create(new orderEntity("ok"));
}
}
這個bean實現一個實際上包含這兩個方法的接口是一個很好的做法。
首先,拋出已檢查的異常通常不會觸發事務回滾,除非您在特定的Exception類型上使用@javax.ejb.ApplicationException(rollback = true)專門為此配置。 未經檢查的異常默認情況下會觸發回滾。
由於Maciej很好地描述了原因,您需要改變嘗試實現此邏輯的方式。 有兩種方法可以實現您想要的行為:
丑陋的方式:
@Stateless
public class MyBean {
@Resource
private SessionContext sessionContext;
@Inject
OrderDAO orderDAO;
public void methodKO() throws Exception {
orderDAO.create(new orderEntity("ko"));
sessionContext.getBusinessObject(MyBean.class).methodOK();
throw new RuntimeException("err");
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void methodOK() {
orderDAO.create(new orderEntity("ok"));
}
}
整潔的方式:
@Stateless
public class MyBean {
@Inject
OrderDAO orderDAO;
public void methodKO() throws Exception {
orderDAO.create(new orderEntity("ko"));
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void methodOK() {
orderDAO.create(new orderEntity("ok"));
}
}
@Stateless
public class MyBusinessBean {
@Inject
private MyBean myBean;
public void businessMethod() {
myBean.methodKO();
myBean.methodOK();
throw new RuntimeException("Trip rollback");
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.