- HttpSession session = request.getSession();
- List<Product> list = session.getAttribute("productCart");
- myService.save(list);
这个对象会被多次使用,也会被同一个用户的多个页面使用,所以他对于系统来说是线程不安全的。 呵呵。偷窥无罪
比如用户在从产品列表里面选择产品,这面选择3种,他点了查看购物车
该用户还开了另一个页面,继续选择产品。
此时,在显示购物车的页面,有可能运行在一半时,其已经选择的产品列表,并另一个页面的操作修改了。所以显示的产品数量有可能并不是3种。
因为session需要维持当前用户的信息,所以其在多个线程里是共享的。所以是线程不安全的。
不过,这个是表面现象,我们只要正确使用事务,保证数据的准确性,表面的问题可以不用管它。
我们可以把session里面的数据另外保存到一个新的数据对象里,这个对象不再因为session的改变而出现变动。这个对象传递给业务层进行事务处理,保证数据级别的准确。
千万不要把session,或者 session里面的对象直接传递给业务层,因为你的业务处理一半时,同样可能出现session对象被改变的情况。有可能造成重要数据出现偏差。
举例:
session 对应三个产品,
事务里面循环了产品,并计算了总价格,
计算完毕,准备保存时,session变了,产品变成了4个。
此时开始保存。产品保存了4个,可总价格却还是3个的。
出现了数据不一致。
修改后的例子
session 对应三个产品
重新生成一个产品对象数组,把session数据复制过来,然后传递给业务层
事务里面循环计算总价格
计算完毕,此时session变了,但并不影响我们这个新的产品数组对象
保存,三个产品,价格也正确。
- HttpSession session = request.getSession();
- List<Product> list = session.getAttribute("productCart");
- List<Product> listNew = new ArrayList<Product>();
- Product pNew;
- for(Product p : list){
- pNew = new Product();
- pNew.setProductId(p.getProductId());
-
- listNew.add(pNew);
- }
- myService.save(listNew);
总结:
有些线程安全问题是很隐蔽的,等你出了问题,很可能根本不认为会是那里出的问题。记住一点,Java里面的对象传递的是对象的引用,只要2个地方用了相同的引用,则其它地方的变动,这一面也会变动。
分享到:
相关推荐
- `HttpSession`:虽然在理论上只被处理同一Session请求的线程访问,但在多窗口或标签页的情况下,仍需注意同步处理以避免数据冲突。 - `ServletRequest`:每个请求对应一个独立的`ServletRequest`对象,因此它是...
Java通过HttpSession接口来实现会话管理,允许开发者存储和检索特定用户的数据。创建会话通常通过HttpServletRequest对象的getSession()方法完成,如果会话不存在,该方法会创建一个新的会话。 Java多线程是并发...
* @return 当前线程中的HttpSession对象 */ public HttpSession getSession() { HttpServletRequest request = requestHolder.get(); if (request != null) { return request.getSession(); } return null; ...
在WEB开发过程中,需要注意多个方面的细节来确保代码的性能和稳定性。以下是一些重要的实践和技巧: 1. **集合和映射对象初始化**:在创建`Collection`和`Map`对象时,应预估所需容量并正确初始化。例如,创建`...
需要注意的是,由于ActionContext在Action实例化时可能还没有完全初始化,所以在Action的构造函数中不应直接使用`ActionContext.getContext()`,因为可能会获取到null值。应在Action的execute方法或其他适当的地方...
需要注意的是,我们使用了CreatePool类来获取数据库连接,该类是一个数据库连接池实现。这种方法可以提高数据库连接的效率和性能。 在valueUnbound方法中,我们没有任何实现,因为我们不需要在对象解绑时执行任何...
开发者需注意线程安全问题,避免在Servlet中使用非线程安全的数据结构或方法。 4. **安全性**: - 认证与授权:可以通过`HttpServletRequest.getUserPrincipal()`获取登录用户信息,`isUserInRole`检查用户角色,...
ActionContext通过ThreadLocal来实现线程隔离,确保每个线程拥有自己独立的ActionContext副本,这样就保证了线程安全性,避免了多线程环境下可能出现的数据冲突。 **ServletActionContext** ServletActionContext...
监听器的实例化和调用由Web容器自动管理,因此需要注意线程安全问题。 4. 监听域对象的创建和销毁: - ServletContext:在Web服务器启动时创建,服务器关闭时销毁。 - HttpSession:当浏览器与服务器建立会话时创建...
但需要注意的是Session对象是非线程安全的。同时,Hibernate的session不同于JSP应用中的HttpSession。这里当使用session这个术语时,其实指的是Hibernate中的session,而以后会将HttpSession对象称为用户session。 ...
在编写Servlet时,需要注意线程安全问题,避免在service方法中修改共享数据。 六、Servlet URL映射 通过web.xml配置或使用@WebServlet注解,可以将Servlet与特定的URL模式关联。例如,通过<url-pattern>/example,...
- 获取HttpSession:`HttpSession session = ServletActionContext.getRequest().getSession();` - ServletActionContext还提供了访问ServletContext、ServletConfig和PageContext的方法,方便进行更底层的Servlet...
`SystemRequestContext`类用于存储当前线程内的`HttpServletRequest`和`HttpSession`对象,以便在过滤器或其他组件中可以方便地获取到这些上下文数据。 - **ThreadLocal**:使用`ThreadLocal`来保存每个线程的私有...
然而,需要注意Session对象是非线程安全的,因此在多线程环境中,每个线程应拥有独立的Session实例。此外,Hibernate的Session不应与Web应用中的HttpSession混淆,后者用于管理用户的会话状态。 2. **...
- 注意线程安全问题,避免在Servlet中使用非线程安全的全局变量。 5. **Servlet会话管理** - `HttpServletRequest`提供了`getSession()`方法获取或创建用户会话。 - `HttpSession`接口用于存储和检索与特定会话...
但这种做法需要注意线程安全问题。 读写文件和访问数据库是Web应用开发中的常见需求。Servlet可以通过Java的文件I/O类来读写文件,同时可以使用JDBC(Java Database Connectivity)API来访问数据库,从而在Web应用...