欢迎使用CSDN-markdown编辑器
来源:互联网 发布:盐城市阳光扶贫大数据 编辑:程序博客网 时间:2024/06/02 05:11
SSH框架整合问题之使用声明式事务管理,hibernate中update操作无效的问题
使用spring声明式事务管理
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory"/><!--配置事务增强处理bean,指定事务管理器 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 配置详细的事务定义 --> <tx:attributes> <!-- 所有以get开头的方法都是只读的--> <tx:method name="get*" read-only="true"/> <!-- 其他方法默认的事务设置,指定超时时长为5秒 --> <tx:method name="*" isolation="DEFAULT" propagation="REQUIRED" timeout="5"/> </tx:attributes> </tx:advice> <aop:config> <!-- 配置一个切入点 --> <aop:pointcut id="myPointcut" expression="bean(readerService)||bean(bookService)"/> <!-- 指定在mypointcut切入点应用txAdvice事务增强处理 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/> </aop:config>
由spring框架统一进行事务管理,在业务逻辑层(service层)目标方法之前开启事务,在方法结束后结束事务。
Service层
public class ReaderServiceImpl implements ReaderService { private IReaderDAO readerDAO; public IReaderDAO getReaderDAO() { return readerDAO; } public void setReaderDAO(IReaderDAO readerDAO) { this.readerDAO = readerDAO; } @Override public int register(Reader baseBean){ String name=baseBean.getName(); String telNum=baseBean.getTelNum(); if(readerDAO.getByName(name)!=null||readerDAO.getByTelNum(telNum)!=null) return -1; //-1.当前用户已注册 else{ readerDAO.save(baseBean); return 1; //1.注册成功 } }@Override public boolean changePassword(Reader baseBean,String newPassword) { Reader reader=readerDAO.get(Reader.class, baseBean.getId()); if(reader.getPassword().equals(baseBean.getPassword())){ reader.setPassword(newPassword); readerDAO.update(reader); return true; }else return false; }
DAO层
public class IDAOImpl implements IDAO { private SessionFactory factory; private ThreadLocal<Session> local=new ThreadLocal<Session>(); public void setFactory(SessionFactory factory){ this.factory=factory; } public SessionFactory getFactory(){ return this.factory; } public Session getSession(){ Session session=local.get(); if(session==null){ session=factory.openSession(); local.set(session); } return session; } @Override public Serializable save(T entity) { Session session=getSession(); Serializable id=session.save(entity); return id; } @Override public void update(T entity) { Session session=getSession(); session.update(entity); }
我这里利用了ThreadLocal线程本地变量,为每一个线程绑定一个Session,以避免Session开启过多,增加开销的情况。
但这里就出现了问题,当调用ReaderServiceImpl的register方法(即调用dao的save方法)是有用的,而调用changePassword方法(即dao的update方法)则无用。
解决方法:
将dao中getSession()改为
public Session getSession(){ return factory.getCurrentSession(); }
分析:
对于Session:
Session是应用程序和数据库层进行交互操作的一个单线程对象,Session是有一个必选的一级缓存的,在显式flush之前,所有的持久化数据都会存在缓存中。
当使用OpenSession打开的Session不会在事务提交时刷新缓存,
而getCurrentSession得到 Session的flushBeforeCompletionEnabled参数为true,会在提交时刷新缓存。
所以update操作会先将更新数据存在一级缓存中,不刷新缓存就是无效。
而save操作有效是因为save方法要求执行方法同时立即执行相应的sql语句,并返回唯一标识符,所以只要事务提交,不刷新缓存也是有效的
1 0
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- 欢迎使用CSDN-markdown编辑器
- linux+命令:命令备注和解析
- 6.如何正确使用Optional-java8新特性
- java 高斯模糊 图片
- 0411-哈夫曼编码
- python爬取百度搜索答案题目和摘要
- 欢迎使用CSDN-markdown编辑器
- zookeeper c api 之Stat结构及封装
- MySql获取插入记录自增主键ID值
- 堆排序
- HDUoj -6019- MG loves gold (set
- JAVA三大特性——继承
- Logistic回归实现鸢尾花分类
- java中将String转化为date,并进行比较
- csrf跨站点伪装请求和xss跨站点攻击