看到一篇描写Java秒杀系统的视频观后总结的博文,写得挺好,里面一些内容有借鉴意义,特此选择其中个人觉得有意义的地方摘录下来,其中的有些知识点(例如Mybatis配置属性)本人并没有全部进行验证,大家采用的时候仅供参考哈!
Mybatis的一些有用的配置属性:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--配置全局属性-->
<settings>
<!--使用jdbc的getGeneratekeys获取自增主键值-->
<setting name="useGeneratedKeys" value="true"/>
<!--使用列别名替换列名  默认值为true
select name as title(实体中的属性名是title) form table;
开启后mybatis会自动帮我们把表中name的值赋到对应实体的title属性中
-->
<setting name="useColumnLabel" value="true"/>
<!--开启驼峰命名转换Table:create_time到 Entity(createTime)-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>
平时配置数据库连接池可能用到的属性:
<!--c3p0私有属性-->
<property name="maxPoolSize" value="30"/>
<property name="minPoolSize" value="10"/>
<!--关闭连接后不自动commit-->
<property name="autoCommitOnClose" value="false"/>
<!--获取连接超时时间-->
<property name="checkoutTimeout" value="1000"/>
<!--当获取连接失败重试次数-->
<property name="acquireRetryAttempts" value="2"/>
避免重复插入数据时抛出异常
如果主键重复插入数据的时候,Mybatis正常是会抛出异常的,我们又不希望它抛出异常,那么我们可以这样做(加上 ignore):
SpringBoot可以使用注解的方式使用事务
在Service中调用事务方法会有些坑,有的可能不会遇到,先记录下来:
- 并发性上不去是因为当多个线程同时访问一行数据时,产生了事务,因此会写锁。每当一个获取了事务的线程把锁释放,另一个排队线程才能拿到写锁,QPS和事务执行的事件有密切关系,事务执行事件越短,并发性越高,这也是要将费时的I/O操作移除事务的原因。
- 同类中调用事务方法的时候还可能有个坑,需要注意AOP切不到调用事务方法,事务不会生效。解决办法可以上网找一个适合自己的方案。 可参考的如下: 1> 如果是基于接口动态代理,直接使用接口调用; 2>如果基于class的动态代理,可以用AopContext.currentProxy()解决,注意玻璃方法一定是public修饰
SpringMVC的一些细节
@DateTimeFormat注解对时间进行格式化!
<!--配置spring mvc-->
<!--1,开启springmvc注解模式
a.自动注册DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter
b.默认提供一系列的功能:数据绑定,数字和日期的format@NumberFormat,@DateTimeFormat
c:xml,json的默认读写支持-->
<mvc:annotation-driven/>
<!--2.静态资源默认servlet配置-->
<!--
1).加入对静态资源处理:js,gif,png
2).允许使用 "/" 做整体映射
-->
<mvc:default-servlet-handler/>
高并发性能优化
秒杀的地址接口可以借助redis来进行优化,不用多次访问数据库。
下面分析瓶颈究竟在哪:
- Mysql执行单条的SQL语句其实是非常快的。
- 主要是行级锁事务的等待,网络的延迟和GC回收!
我们之前的逻辑是这样的:先执行减库存操作,再插入购买成功的记录
其实,我们可以先插入成功购买的记录,再执行减库存的操作!
- 那这两者有啥区别呢???减库存的操作会导致行级锁的等待,而我们先进行insert的话,那么就不会被行级锁所干扰了。并且,我们这中两个操作是在同一个事物中的,并不会出现“超卖”的情况!
关于先执行insert与先执行update的区别:
两个事务同时insert的情况下,没有锁竞争,执行速度会快,当两个事务先update同一行数据,会有一个事务获得行锁,锁在事务提交之前都不会释放,所以让锁被持有的时间最短能提升效率
以上,完结。
文章来源:
作者:Java3y
链接:https://juejin.im/post/5aabd1956fb9a028d82b8738