`
y806839048
  • 浏览: 1127689 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

用切面的方式实现全局性的乐观锁

阅读更多

 

用切面的方式实现全局性的乐观锁

 

乐观锁的思路update的查询条件加version,update的时候version+1

 

用拦截器拦截ibatis的updat方法(不是我们业务中的update方法),在sql中加入version的操作

 

 @Override

public Object intercept(Invocation invocation) throws Throwable {

    if ((invocation.getArgs() != null) && (invocation.getArgs().length > 0) && (invocation.getArgs()[0] != null)
            && ((invocation.getArgs()[0] instanceof MappedStatement))) {

        MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
        Object obj = invocation.getArgs()[1];
        if (ms.getSqlCommandType() != SqlCommandType.UPDATE) {
            log.debug("非更新语句,不需要乐观锁!");
        } else {
            if (obj == null) {
                return invocation.proceed();
            }
            if (obj != null && obj.getClass().isAnnotationPresent(VersionIgnored.class)) { // 如果标明不需要乐观锁
return invocation.proceed();
            }
            Field field = getField(obj, "version");
            if (field == null) {
                throw new RuntimeException("乐观锁的控制的参数必须包含version字段,且是普通PO对象");
            }
            Integer version = (Integer) getFieldValue(obj, "version");
            Method versionSetter = obj.getClass().getMethod("setVersion", Integer.class);
            if(version == null || versionSetter == null){
              throw new RuntimeException("乐观锁的控制的参数必须包含version字段不能为null, setVersion方法保持public状态");
            }
            SqlSource sqlSource = ms.getSqlSource();
            BoundSql boundsql = sqlSource.getBoundSql(obj);
            String sql = boundsql.getSql();
            String sqlparts[] = sql.split("[wW][hH][Ee][Rr][Ee]");
            String newsql;
            newsql = sqlparts[0] + ",version=version+1  where" + sqlparts[1] + " and version=" + version;
            BoundSql myBoundSql = new BoundSql(ms.getConfiguration(), newsql, boundsql.getParameterMappings(),
                    boundsql.getParameterObject());

            MappedStatement newms = copyFromMappedStatement(ms, new MyBoundSqlSource(myBoundSql));
            invocation.getArgs()[0] = newms;
            Object num = invocation.proceed();
            if (num != null && !"1".equals(num.toString())) {
                throw new RuntimeException("乐观锁版本不对");
            }
            versionSetter.invoke(obj, version + 1);
            return num;
        }
        return invocation.proceed();
    } else {
        return invocation.proceed();
    }
}
分享到:
评论

相关推荐

    2024年java面试题

    - AOP(Aspect-Oriented Programming,面向切面编程)提供声明式事务管理等功能。 - Spring中的Bean作用域包括singleton(单例)、prototype(原型)、session(会话)和global-session(全局会话)。 - Spring ...

    Java面试可能问的问题.docx

    【Java面试可能问的问题】 1. **Spring的AOP(面向切面编程)**:AOP...21. **并发操作库存**:库存操作需要原子性,可以使用数据库事务、乐观锁或分布式锁来确保一致性。例如,通过加版本号控制并发更新,防止脏读。

    struts2、hibernate、spring学习总结文档

    9. 锁机制:包括悲观锁和乐观锁,处理并发问题。 Spring篇: 1. IOC/DI:Inversion of Control和Dependency Injection,Spring通过容器管理对象及其依赖关系。 2. BeanFactory与ApplicationContext:Spring的两种...

    郑州数字马力面试(后台java)经验

    Spring框架最大的优势在于其强大的依赖注入(DI)能力,能够极大地简化Java应用程序的开发过程,同时提供了AOP(面向切面编程)、声明式事务管理等功能。 **14. Dubbo与Netty** Dubbo是一个高性能、轻量级的微服务...

    java面试题目

    - **Spring AOP与代理模式**:Spring的AOP(面向切面编程)通常基于代理模式实现,用于添加日志记录等功能,而不会修改现有业务逻辑。 #### 12. 集合的分类与原理 - **集合框架**:Java集合框架主要包括`...

    百度面试题汇总(java)

    21. **乐观锁与悲观锁**:乐观锁假设冲突较少,每次更新数据前检查版本号;悲观锁假设冲突较多,通过加锁防止冲突。 22. **数据库索引类型**:主要有B-Tree索引、哈希索引、全文索引等。 23. **事务传播级别**:...

    Java面试题和答案.pdf

    - 在对象级上使用锁标记字段,通过`monitorenter`和`monitorexit`指令实现锁的获取和释放。 **53. `synchronized`和`volatile`的区别是什么?** - **`synchronized`**: 保证线程安全、原子性和可见性,有锁机制。 ...

    Java 面试资料 进阶版

    - **面向切面编程(AOP)**: 提供了一种将横切关注点模块化的方法,使得应用程序业务逻辑各部分之间的耦合度降低。 - **MVC模式**: Model-View-Controller模式,是一种软件架构模式,用来开发易于维护和修改的应用程序...

    J2EE武功秘籍

    - **面向切面编程**(Aspect Oriented Programming, AOP): - 将横切关注点从业务逻辑中分离出来。 **2. Struts和Struts2框架** - **Struts**: - 基于MVC架构的Web应用框架。 - 主要用于Java EE应用。 - **...

Global site tag (gtag.js) - Google Analytics