2011-02-24 26 views
18

Yayında, @Transactional ile açıklamalı bir yöntem, zaten mevcut değilse yeni bir işlem alacak, ancak bir işlem yönteminin herhangi bir işlem olmayan birinden çağrılırsa işlem. İşte kod.@ Başka bir yöntemden başka bir yöntemden çağrılan işlem yöntemi, bir işlem elde edemiyor

@Component 
public class FooDao { 
    private EntityManager entityManager; 

    @PersistenceContext 
    protected void setEntityManager(EntityManager entityManager) { 
     this.entityManager = entityManager; 
    } 

    @Transactional 
    public Object save(Object bean) { 
     return this.entityManager.merge(bean); 
    } 

    public Object saveWrap(Object bean) { 
     return save(bean); 
    } 
} 

@Component 
public class FooService { 
    private FooDao fooDao; 

    public void save(Object bean) { 
     this.fooDao.saveWrap(bean); // doesn't work. 
     this.fooDao.save(bean); // works 
    } 
} 

saveWrap() işlem olup save() çağırıyor ama saveWrap() herhangi bir değişiklik kalıcı olmaz düzenli yöntemdir.

İlkbahar 3 ve Hazırda Bekletme 3 kullanıyorum. Burada ne yapıyorum? Teşekkürler.

cevap

30

Yaylar AOP'nin sınırlamalarından biridir. Dao fasulyesi, ilkbaharda yaratıldığı zaman aslında bir vekil olduğu için, aynı sınıftan bir yöntemin çağrılması, tavsiyeyi (işlem olan) çağırmayacaktır. Aynı durum başka herhangi bir nokta için de geçerlidir.

+2

@Transactional ile saveWrap yöntemini ek açıklamada herhangi bir zarar yoktur. İşlem yayılımı ile varsayılan davranış GEREKTİRİR, yani iç içe geçmiş bir işlem (yani, bir işlemde iseniz ve daha sonra da [Transactional] olan başka bir yöntemi çağırırsanız), yalnızca mevcut işlemi kullanmak ve OLMAYACAKSINIZ başka bir tane korktuğunuz şey ise) –

+0

proxy için cglib kullanımı hakkında ne dersiniz? Ben cglib vekil tavsiyesini, aynı sınıf içinde bile çağırdığınız her yöntemi hatırlıyorum. – hiway

11

Evet, bu beklenen bir davranıştır. @Transactional, nesnenin etrafında bir proxy oluşturmak için yayı anlatır. Proxy, diğer nesnelerden nesneyi çağırır. Proxy, nesne içindeki çağrıları engellemez.

Bu işi yapmak istiyorsanız, "dış" modundan çağrılan yönteme @Transactional ekleyin.

+1

Başka bir seçenek, sınıfın üst kısmında @Transactional() (muhtemelen readOnly = true/false, propagation = bir şey vb.) Yerleştirerek ve sonra readOnly ve/veya propagasyonunu geçersiz kılarak tüm sınıfı işlemsel olarak işaretlemek olurdu. Gerektiğinde yönteme göre değerler. – esaj

2

Bu biraz geç olduğunu biliyorum, ancak bu sınırlamanın üstesinden gelmek için bir yol eklemek ister, yöntem içinde yöntemde yay fasulyesini elde eder ve yöntemi çağırır. Bahar fasulyesi uygulama bağlamından alındığında, orijinal fasulye değil vekil fasulye olacaktır. Proxy fasülyesi artık orijinal fasülye yerine metodu çağırdığından, işlem tavsiyesi uygulanacaktır.

İlgili konular