最近写一个转账需求向外提供接口,用的是spring+struts2+maven 方式,数据库是oracle。我先新建maven类,然后引入spring相关jar包和mybatis包,配置struts.xml、applicationContext.xml、log4j等;
然后写了一个测试action类,测试部署是否正确,遇到的问题大概有jar包冲突,struts中action路径错误,扫描不到dao包等等,这是前期搭建环境时的问题;
正式开发转账逻辑时,遇到的问题大概有mybatis类型不匹配,其中折腾较久的是mybatis查询数据库时,查不到数据,而用DbVisualizer、pqsql等工具可以查到。最开始猜测可能是缓存问题,最新插入的数据只存在数据还没有被缓存;
然后关闭缓存再查询,依然查不到,再猜测可能是事物原因,于是降低数据库隔离级别然后再查,结果依然查不到。 最后打印出sql,发现sql中一个字段与parameterType插入的字段不匹配!因为mybatis不打印sql并且之前测试查询sql时也可以查到,
所以就没有想过是sql原因。。
开发中还有一个折腾比较久的是注入属性,结合spring mvc的经验,我直接在spring配置中加入自动扫描组件<context:component-scan base-package="com.xxx.dao" />,然后使用注解autowired和resource均失败,然后写上被注入类的getter、
setter方法和无惨构造器,依然不行。最后又写一个测试类,一步一步测试,发现注入的类的父类构造参数有问题,加上构造器 ,然后检查applicationContext里的bean引入是否正确,遂解决。
开发后期的主要问题是多线程问题,因为之前一直没用使用多线程,后期加入多线程后,发现获取不到ActionContext,debug前后查看多线程ActionContext的值,发现线程启动前有值,新启线程后无值,然后加入voliate修饰词后便能获取值,
但是又有新问题,voliate只能让变量可见,但是不能保证线程安全,volatile可以保证线程可见性且提供了一定的有序性,但是无法保证原子性,在JVM底层volatile是采用“内存屏障”来实现的。虽然通过它让ActionContext可见,但是当需要返回
http请求时,返回不了,
ActionContext ctx = ActionContext.getContext(); HttpServletResponse response =(HttpServletResponse)ctx.get(ServletActionContext.HTTP_RESPONSE); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("text/html;charset=UTF-8"); response.getWriter().write(str);; response.getWriter().flush();
response.getwriter.flush() 方法报错,猜测是因为新起的线程后,response作用域失效,找不到请求的路径,自然无法返回。