spring controller 拦截且异步处理

场景:

  对spring mvc的controller进行拦截,且在s(springmvc)s(spring)h(hibernate)环境中异步处理数据。

问题:

1 spring aop配置:

   如果是对service/dao进行拦截处理,在applicationContext.xml中配置且点/处理切面等数据(项目中此文件名称会变化);

 如果是对controller进行拦截出,在servlet.xml中配置且点/处理切面等数据(项目中此文件名称会变化);

具体不同主要是因为controller和service/dao的初始化时间不一致,如果配置错误,将不能对对应的类进行正确的aop增强,导致aop无效(可以参考代理的原理)。

2 hibernate的session问题:

   在ssh环境中,为了保证session的一致性,spring通过filter在请求创建时对线程进行了绑定,保证controller/service/dao使用的是同一个session;但是如果我们使用线程池创建线程对数据进行处理,不存在绑定问题,在查询实体关联属性的时候会出现session提前关闭。具体异常如could not initialize proxy - no Session(即使你使用官方ThreadLocal绑定session,但是在dao拿到的session和此时绑定的必然不一样),解决方法,如下:

 

 // 创建session给TransactionSynchronizationManager

    /**reference OpenSessionInViewFilter.doFilterInternal*/
    public void sessionToSpring() {
        // single session mode
        if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
            // Do not modify the Session:
        } else {
            Session session = getSession(sessionFactory);
            TransactionSynchronizationManager.bindResource(sessionFactory,
                    new SessionHolder(session));
        }
    }
    // 创建session
    /**copy OpenSessionInViewFilter.getSession*/
    public Session getSession(SessionFactory sessionFactory) {
        Session session = SessionFactoryUtils.getSession(sessionFactory, true);
        FlushMode flushMode = FlushMode.MANUAL;
        if (flushMode != null) {
            session.setFlushMode(flushMode);
        }
        return session;
    }
    // 关闭
    /**reference OpenSessionInViewFilter.doFilterInternal*/
    public void sessionClose() {
        SessionHolder sessionHolder =
                (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
        SessionFactoryUtils.closeSession(sessionHolder.getSession());
    }

 

 

 

 

  另外,这样只是解决了session问题,但是如果你需要用到事务,你会发现问题依然存在,spring的事务标记 没有作用,同样session问题。因为此时你操作数据的session和代理生成的session不一致,不能正确的把你的数据进行提交回滚。解决方式:

1 获得spring配置时配置的事务管理器

@Autowired
private HibernateTransactionManager transactionManager;

private TransactionDefinition definition = new DefaultTransactionDefinition();

 

2 在事务起始地点 获取事务

TransactionStatus status = transactionManager.getTransaction(definition);

 

3 在事务结束地点 提交事务 或回滚事务 

 transactionManager.commit(status);

 transactionManager.rollback(status); 

 

具体可以看源码,原理核心就是将一个session和事务起始点、结束点能对应起来。

转载于:https://www.cnblogs.com/codermaster/p/4137369.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值