使用的事务管理是
org.springframework.jdbc.datasource.DataSourceTransactionManager
一、刚开始事务是这样实现的
TransactionStatus ts = transactionManager.getTransaction(null); try { // 得到用户信息 User user = userMapper.selectByPrimaryKey(userId); user.setHealthBeans(user.getHealthBeans() == null ? 0 : user.getHealthBeans()); Article article = articleMapper.selectByPrimaryKey(articleId); User createrUser = userMapper.selectByPrimaryKey(article.getCreater()); HealthBeansRecord record = new HealthBeansRecord(); healthBeansRecordMapper.insertSelective(record); record.setNumber((byte) +exceptionalCount); healthBeansRecordMapper.insertSelective(record); userMapper.modifyHealthBeans(userId, -exceptionalCount); userMapper.modifyHealthBeans(createrUser.getId(), exceptionalCount); transactionManager.commit(ts); } catch (Exception e) { transactionManager.rollback(ts); throw new BasicException(String.format("出现异常,异常原因:%s,参数userId:%s,参数articleId:%s", e.getMessage(), userId, articleId), e); }
但是会时不时的出现:
### Error updating database. Cause: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction ### The error may involve defaultParameterMap ### The error occurred while setting parameters
二、改成如下方式
try { ts = transactionManager.getTransaction(null); // 得到用户信息 User user = userMapper.selectByPrimaryKey(userId); user.setHealthBeans(user.getHealthBeans() == null ? 0 : user.getHealthBeans()); Article article = articleMapper.selectByPrimaryKey(articleId); User createrUser = userMapper.selectByPrimaryKey(article.getCreater()); HealthBeansRecord record = new HealthBeansRecord(); healthBeansRecordMapper.insertSelective(record); record.setUserId(createrUser.getId()); record.setNumber((byte) +exceptionalCount); healthBeansRecordMapper.insertSelective(record); userMapper.modifyHealthBeans(userId, -exceptionalCount); userMapper.modifyHealthBeans(createrUser.getId(), exceptionalCount); transactionManager.commit(ts); } catch (Exception e) { transactionManager.rollback(ts); throw new BasicException(String.format("出现异常,异常原因:%s,参数userId:%s,参数articleId:%s", e.getMessage(), userId, articleId), e); }
将TransactionStatus的声明为类的成员变量,在try catch中完成事务的使用。这样锁超时的错误少了很多,但是还会出现超时的情况
三、给使用事务的代码添加类级异步锁
try { synchronized (getClass()) { ts = transactionManager.getTransaction(null); // 得到用户信息 User user = userMapper.selectByPrimaryKey(userId); user.setHealthBeans(user.getHealthBeans() == null ? 0 : user.getHealthBeans()); Article article = articleMapper.selectByPrimaryKey(articleId); User createrUser = userMapper.selectByPrimaryKey(article.getCreater()); HealthBeansRecord record = new HealthBeansRecord(); healthBeansRecordMapper.insertSelective(record); record.setUserId(createrUser.getId()); record.setNumber((byte) +exceptionalCount); healthBeansRecordMapper.insertSelective(record); userMapper.modifyHealthBeans(userId, -exceptionalCount); userMapper.modifyHealthBeans(createrUser.getId(), exceptionalCount); transactionManager.commit(ts); } } catch (Exception e) { transactionManager.rollback(ts); throw new BasicException(String.format("出现异常,异常原因:%s,参数userId:%s,参数articleId:%s", e.getMessage(), userId, articleId), e); }
这样一来,经过测试,不再出现锁超时的情况了。
但是总感觉,这样的异步控制是不应该在业务代码中进行控制的!
相关推荐
Spring Cloud是基于Spring Boot的微服务解决方案,涵盖了服务发现、负载均衡、断路器、配置中心等多个组件。面试中会讨论如何使用Spring Boot构建应用,以及Spring Cloud的组件功能和应用场景。 【Hibernate/...
Java面试题精选涵盖了Java语言的核心概念、数据结构与算法、多线程、网络编程、集合框架、设计模式、JVM优化、Spring框架、数据库、分布式系统等多个方面,这些都是Java开发者在面试过程中可能会遇到的关键问题。...
- Spring框架:依赖注入(DI),AOP,事务管理,Spring Boot,Spring Cloud等。 - MyBatis:SQL映射,动态SQL,MyBatis Plus增强工具。 - MVC框架:Spring MVC的工作原理,控制器,模型,视图解析器等。 9. **...
8. **框架**:常见的Java Web框架如Spring、MyBatis、Hibernate等,面试中可能要求了解其工作原理,如Spring的依赖注入、AOP(面向切面编程),MyBatis的动态SQL以及Hibernate的对象关系映射。 在准备这些知识点时...
5. **软件工程原则**:论文可能涵盖了软件开发的全过程,包括需求分析、系统设计、编码、测试和维护。敏捷开发、模型驱动开发(MDD)、统一建模语言(UML)等方法论可能在设计过程中被提及。 6. **Java Web开发**:...
JavaEE面试宝典是每一位Java开发者在求职过程中必备的参考资料,涵盖了从基础知识到高级技术的全方位面试准备。这里,我们将深入探讨其中的关键知识点,帮助你更好地理解和掌握。 首先,我们从基础开始。Java语言的...
1. Spring框架:依赖注入(DI),面向切面编程(AOP),Spring Bean的生命周期,事务管理,以及Spring Boot的使用。 2. MyBatis:动态SQL,Mapper接口,XML配置和注解方式,以及MyBatis的缓存机制。 3. Hibernate:...
Spring、MyBatis、Hibernate等主流Java框架的使用和原理也常常出现在面试题中。理解IoC(控制反转)、AOP(面向切面编程)等概念,以及如何进行性能优化,有助于在实际工作中解决问题。 九、算法与数据结构 虽然...
-事务处理:ACID属性,事务隔离级别,以及死锁问题。 - ORM框架:Hibernate、MyBatis的工作原理和使用技巧。 8. **网络编程** - TCP/IP协议:理解TCP三次握手、四次挥手过程,以及拥塞控制算法。 - HTTP协议:...
- MyBatis:动态SQL,Mapper接口,事务控制。 - Spring Boot和Spring Cloud:快速开发和微服务架构。 以上只是部分Java面试中可能涉及的关键知识点,通过阅读《Java面试宝典》等资料,可以深入学习和理解这些内容...
8. **数据库**: SQL语言的熟练使用,包括查询、更新、删除、插入操作,以及索引、事务、存储过程、视图等高级特性。对关系型数据库如MySQL、Oracle,以及NoSQL数据库如MongoDB的理解也是重要的面试内容。 9. **其他...
- **死锁**:理解死锁的概念,如何避免和解决死锁问题。 - **线程池**:掌握ExecutorService,ThreadPoolExecutor,ScheduledExecutorService的使用。 5. **并发编程** - **并发工具类**:熟悉ConcurrentHashMap...
- 公司特定的技术栈,如Spring Boot、Spring Cloud、MyBatis等。 - 架构设计:微服务、RESTful API设计、分布式系统架构。 - 性能优化:JVM调优,内存管理,垃圾回收机制。 - 数据库知识:SQL查询,索引原理,...
除此之外,面试还可能涉及JVM内存模型、垃圾回收机制、类加载器,以及Spring Boot、MyBatis等常用框架的应用和优化。对于更高级的面试,你可能需要对分布式系统、微服务架构、设计模式有深入的理解。 总的来说,这...
9. **数据库相关**:SQL语言的基本操作,如CRUD(创建、读取、更新、删除),了解索引、事务、存储过程等高级特性。对JDBC(Java Database Connectivity)有深入理解,包括连接池的使用。 10. **框架知识**:Spring...
11. **Spring框架**:Spring的IoC容器、AOP、MVC模式、事务管理、MyBatis集成等。面试中会考察你如何使用Spring进行依赖注入,以及在实际项目中的应用经验。 12. **JVM内存管理**:了解堆、栈、方法区、元空间等...
Java生态系统中有许多成熟的框架和工具,如Spring、MyBatis、Hibernate、Redis等。理解这些框架的设计原理、优缺点及应用场景对于实际开发工作非常有帮助。 1. **Spring**:一个轻量级的开源框架,主要提供依赖注入...
- Spring Bean的生命周期:创建、初始化、销毁的过程。 - Spring MVC:控制器、模型、视图解析、拦截器。 - Spring Boot:自动配置、起步依赖、微服务化。 以上内容涵盖了Java开发人员面试中常见的知识点,深入...
这份文档旨在帮助Java程序员在面试过程中展现出扎实的技术功底和良好的问题解决能力。 一、Java基础 1. Java语法:理解并掌握类、对象、接口、继承、多态等核心概念。 2. 内存管理:了解Java内存模型,包括堆、栈、...
- Spring框架:IoC容器、AOP、事务管理、Spring Boot和Spring Cloud的应用。 - MyBatis:动态SQL、缓存机制、Mapper接口的使用。 - Maven或Gradle构建工具:项目依赖管理,构建流程。 7. **数据库**: - SQL...