<dependency> <groupId>org.apache.deltaspike.modules</groupId> <artifactId>deltaspike-jpa-module-api</artifactId> <version>${deltaspike.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.deltaspike.modules</groupId> <artifactId>deltaspike-jpa-module-impl</artifactId> <version>${deltaspike.version}</version> <scope>runtime</scope> </dependency>
<beans> <!-- Not needed with CDI 1.1+ and DeltaSpike v1.1.1+ --> <interceptors> <class>org.apache.deltaspike.jpa.impl.transaction.TransactionalInterceptor</class> </interceptors> </beans>
//no javaEE Server public class EntityManagerProducer { //or manual bootstrapping @PersistenceContext private EntityManager entityManager; @Produces @RequestScoped protected EntityManager createEntityManager() { return this.entityManager; } protected void closeEntityManager(@Disposes EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } } } //EE-Server @ApplicationScoped public class EntityManagerProducer { @PersistenceUnit private EntityManagerFactory entityManagerFactory; @Produces @Default @RequestScoped public EntityManager create() { return this.entityManagerFactory.createEntityManager(); } public void dispose(@Disposes @Default EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } } }
下面的例子显示如何使用 EntityManager,@Transactional
//bean与事务方法 public class TransactionalBean { @Inject private EntityManager entityManager; @Transactional public void executeInTransaction() { //... } } //... @Transactional public class TransactionalBean { @Inject private EntityManager entityManager; //... }
也可以通过CDI stereotypes 来使用
@Stereotype @Transactional @ApplicationScoped public @interface Repository { } //... @Repository public class TransactionalBean { @Inject private EntityManager entityManager; //... }
下面是系统存在多个persistence-units的使用方法,使用cdi qualifiers进行配置使用.
//... public class EntityManagerProducer { @PersistenceContext(unitName = "firstDB") private EntityManager firstEntityManager; @PersistenceContext(unitName = "secondDB") private EntityManager secondEntityManager; @Produces @First @RequestScoped protected EntityManager createFirstEntityManager() { return this.firstEntityManager; } protected void closeFirstEntityManager(@Disposes @First EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } } @Produces @Second @RequestScoped protected EntityManager createSecondEntityManager() { return this.secondEntityManager; } protected void closeSecondEntityManager(@Disposes @Second EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } } } //... public class FirstLevelTransactionBean { @Inject private @First EntityManager firstEntityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { //... this.nestedTransactionBean.executeInTransaction(); } } //... public class NestedTransactionBean { @Inject private @Second EntityManager secondEntityManager; @Transactional public void executeInTransaction() { //... } }
下面的例子是使用指定的EntityManager
public class MultiTransactionBean { @Inject private EntityManager defaultEntityManager; @Inject private @First EntityManager firstEntityManager; @Inject private @Second EntityManager secondEntityManager; @Transactional(qualifier = Default.class) public void executeInDefaultTransaction() { } @Transactional(qualifier = First.class) public void executeInFirstTransaction() { } @Transactional(qualifier = Second.class) public void executeInSecondTransaction() { } @Transactional(qualifier = {First.class, Second.class}) public void executeInFirstAndSecondTransaction() { } }
事务的嵌套使用
//... public class FirstLevelTransactionBean { @Inject private EntityManager entityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { this.nestedTransactionBean.executeInTransaction(); } } //... public class NestedTransactionBean { @Inject private EntityManager entityManager; @Transactional public void executeInTransaction() { //... } }
如果FirstLevelTransactionBean和NestedTransactionBean使用的EntityManager不一样.那么在FirstLevelTransactionBean处将引发异常.
for example, to try an optional path instead of an immediate rollback.[它会尝试一个可选的路径去做,而不是立即回滚,如果可选的还不行,再回滚.我个人理解,不知道是否正确.]略...... http://deltaspike.apache.org/documentation/jpa.html#__transactionscoped
略..... http://deltaspike.apache.org/documentation/jpa.html#_extended_persistence_contexts
除了在配置文件时指明了事务的类型,不同的事务类型,不同类型的EntityManager对象,在代码中控制事务也是不同的。
By default the transaction-type used by @Transactional is RESOURCE_LOCAL. If you configure transaction-type="JTA" in the persistence.xml file, you have to enable an alternative TransactionStrategy in the beans.xml which is called org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy.<beans> <alternatives> <class>org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy</class> </alternatives> </beans>If you have multiple persistence-units and you have to use both transaction-types or the settings for development have to be different than the production settings, you can use org.apache.deltaspike.jpa.impl.transaction.EnvironmentAwareTransactionStrategy instead.