我写了一个简单的webapp在Tomcat5.5.12上面做了一个小测试。在JSP页面里面循环1万次输出字符串,程序在远程服务器上面运行,网络是ADSL宽带,filter确实被阻塞了20秒左右。然后我另外开了一个flashget去下载服务器上的大文件,模拟网络速度比较慢的环境,filter被阻塞了50秒左右。分别做了三次测试。另外当页面下载过程中直接点击浏览器stop按钮,则JSP执行被打断,filter立刻解除阻塞,被执行完毕。
结论证明,使用OpenSessionInView的时候,如果render的页面数据量非常大,并且客户端网络速度很慢的情况下,由于页面的输出时间过程很长,确实会造成filter被长时间阻塞。对于OpenSessionInViewFilter来说,就会造成数据库连接被保持很长的时间,才能被关闭。
不过,对于Spring的OpenSessionInViewFilter来说,虽然数据库连接被保持了过长的时间,但是并没有锁定数据库资源,特别是事务资源。[b]因为Spring的事务是通过TransactionInterceptor来实现的,在MVC结构中,当最后一个业务bean被调用结束以后,Transaction就已经被提交了。此后,虽然数据库连接还保持中,但是数据库资源没有锁定问题。[/b]
完整的调用示意图:
request -> (OpenSessionInViewFilter打开Session) -> ServletDispatcher -> Action -> (打开Connection,启动事务) -> spring bean -> another spring bean -> (提交事务) -> bean执行完毕,返回Action -> render view(JSP/Template) -> (OpenSessionInViewFilter关闭Session和Connection)
结论证明,使用OpenSessionInView的时候,如果render的页面数据量非常大,并且客户端网络速度很慢的情况下,由于页面的输出时间过程很长,确实会造成filter被长时间阻塞。对于OpenSessionInViewFilter来说,就会造成数据库连接被保持很长的时间,才能被关闭。
不过,对于Spring的OpenSessionInViewFilter来说,虽然数据库连接被保持了过长的时间,但是并没有锁定数据库资源,特别是事务资源。[b]因为Spring的事务是通过TransactionInterceptor来实现的,在MVC结构中,当最后一个业务bean被调用结束以后,Transaction就已经被提交了。此后,虽然数据库连接还保持中,但是数据库资源没有锁定问题。[/b]
完整的调用示意图:
request -> (OpenSessionInViewFilter打开Session) -> ServletDispatcher -> Action -> (打开Connection,启动事务) -> spring bean -> another spring bean -> (提交事务) -> bean执行完毕,返回Action -> render view(JSP/Template) -> (OpenSessionInViewFilter关闭Session和Connection)