发新话题
打印

spring 中的事务管理

spring 中的事务管理

applicationContext.xml
-------------------------------------------------------------------------------------------------
<aop:config>
                <aop:pointcut id="serviceMethods"
                        expression="
                        execution(* xform.services.MyService.*(..))" />

                <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods" />
        </aop:config>

        <tx:advice id="txAdvice" transaction-manager="jatoolsTxManager">
                <tx:attributes>
                        <tx:method name="*" propagation="REQUIRED" />
                </tx:attributes>
        </tx:advice>
----------------------------------------------------------------------------------------------------
以上声明MyService接口的任意方法,都需要进行事务管理。


public class LoginAction extends ActionSupport
{
    @Autowired
    @Qualifier("myService")
    private MyService myService = null;
...
当LoginAction创建时,让spring自动注入一个 MyService实例。Spring从何处得到一个 MyService?答案是,从一个注释Component为myService创建

@Component("taskService")
public class MyServiceImpl implements MyService {
...

当进入LoginAction类execute方法,如:
   public String execute() throws Exception {
        myService.getSomething(); //让我们来看看,这里发生了什么?


   }

调试时,可看到 myService对象的类型,不是MyServiceImpl,而是一个Proxy,具有MyService接口,代理的实例,就是MyServiceImpl, 任何对Proxy的调用,最后都会被转发到MyServiceImpl对象。本例中,调用的是getSomething方法,在被转发到MyServiceImpl.getSomething之前会进行事务处理,Proxy是什么,实际上,可以看作实例MyService的另一个对象,如下:

class Proxy implements MyService
{
    MyServiceImpl delegate;
    public Object getSomething()
    {
         // 这里事务处理

         return delegate.getSomething();

    }

}

具体实现,是通过Proxy+interceptor来完成,有关事务的interceptor是TransactionInterceptor
TransactionInterceptor 类,有两个属性,一个是事务管理器,用来创建事务tx。一个是事务规则集rules,可以从中找到对应类,方法,用到的事务规则,事务规则定义隔离级别,是否必须事务等

public Object getSomething()
    {
         // 这里事务处理

        TransactionInterceptor ti = ...
        TransactionDefinition definition = 取事务规则(getSomething方法,MyService接口)
        ti.tx.getTransaction(definition)
            {
                  HibernateTransactionObject hto=new
                  if(本线程中,已经有被spring管理的session)
                      sessionholder -> hto
                  如果有hibernate自己管理的session,HS则-> hto
                  如果不存在任何session ,则 从datasource -> connectionholder -> hto

                  如果存在事务,
                     则。。。
                  
                  如果不存在事务,
                      且difinition是PROPAGATION_MANDATORY报错
                      else 从connectionHolder中,创建一个事务
                           doBegin(Object transaction, TransactionDefinition definition)
                           {
                               session = getSessionFactory().openSession()
                               Transaction tx = session.begin();

                               hto.getSessionHolder().setTransaction(tx);
                               hto.setConnectionHolder(session.connection());

                               注册thread(getDataSource(), ConnectionHolder)
                               注册thead(getSessionFactory(), hto.getSessionHolder())

                               以后可以从 thread中,找到 sessionholder,从而发现是否已经存在session,和事务
                           }
            }
         return delegate.getSomething();
    }

TOP

发新话题