私の環境を簡単に説明しようとします。テクノロジー: EJB 3.1、JSF、JBoss 7.1.1
サービス クラス (@SessionScoped @Stateful) があります。サービス クラスは Dao クラスを呼び出します (@Stateless)
が欲しいです :
- EntityManager を @StateLess Bean (Dao) にのみ使用する
- ほとんどの場合、トランザクションが短い (持続、マージなど)
- いくつかの多段階メソッドに対して 1 つの長いトランザクションがあります (メソッドは Dao にもあります)
- 実際の (最新の、一次キャッシュなしの) データを持っている
私が持っている: Pesistense.xml
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/MydataSource</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.dialect"value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<property name="hibernate.connection.autocommit" value="true"/>
<property name="hibernate.connection.characterEncoding" value="utf8"/>
<property name="hibernate.c3p0.min_size" value="5"/>
<property name="hibernate.c3p0.max_size" value="20"/>
<property name="hibernate.c3p0.timeout" value="1800"/>
<property name="hibernate.c3p0.max_statements" value="50"/>
</properties>
</persistence-unit>
ダオ
@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class UserDaoBean implements UserDAO, Serializable {
@PersistenceContext(name = "MyEntityManager")
private EntityManager em;
@Override
@Transactional
public void update(User user) throws Exception {
User tmpUser = getUser(user.getUser());
//some code, should be rollback, if it is an exception
em.persist(tmpUser);
}
トランザクションインターセプター
@Transactional
@Interceptor
public class TransactionInterceptor implements Serializable {
@Resource
private UserTransaction userTransaction;
@AroundInvoke
public Object verifyAccess(InvocationContext context) throws
Exception {
Object result = null;
try {
userTransaction.begin();
result = context.proceed();
userTransaction.commit();
} catch (Exception e) {
userTransaction.rollback();
throw new CustomRuntimeException(e.getMessage());
}
return result;
}
}
問題: Dao メソッドに例外をスローすると、完全なロールバックではなく、部分データが DB に保存されます。
EM への Join Transaction が必要だと思います。または、切断すると、各アイテムがすぐに DB に永続化されます (キャッシュを使用)。さまざまな方法を試しましたが、成功しませんでした。
よろしくお願いします!