悲观锁"/>
实践检验乐观锁与悲观锁
前言
在实际生产环境中,往往会遇到热门的产品,导致短时间内大量用户涌入。比如某款新手机上市,会在某个时间点开抢,这时就需要面对这个高并发现象。
我们就通过简单的模拟实验,复现这个场景并解决。
模拟过程(这里针对单一商品,一次只能购买一个)
环境配置并测试
直接使用Mybatis作为我们的持久层框架。
1、搭建Mybatis环境(参考:Mybatis快速开始)。建立如下两张表和相应持久层对象。
商品明细表(tb_product)
购买记录表(tb_purchase_record)
2、到层接口和对应的mapper文件(就查库存、减库存、增加购买记录三个相应的方法)
public interface ProductDao {//根据id查询库存int getProductRepertoryById(Integer productId);//更改库存int updateProductRepertoryById(Integer productId);
}
<mapper namespace="com.zepal.mybatis.dao.ProductDao"><select id="getProductRepertoryById" parameterType="int" resultType="int">select product_repertory from tb_product where product_id = #{productId};</select><update id="updateProductRepertoryById" parameterType="int">update tb_product set product_repertory = product_repertory - 1where product_id = #{productId};</update>
</mapper>
public interface PurchaseRecordDao {//增加购买记录int savePurchaseRecord(PurchaseRecord purchaseRecord);
}
<mapper namespace="com.zepal.mybatis.dao.PurchaseRecordDao"><insert id="savePurchaseRecord" useGeneratedKeys="true" parameterType="com.zepal.mybatis.domain.PurchaseRecord">insert into tb_purchase_record (record_person, record_time, product_id)values(#{recordPerson}, #{recordTime}, #{product.productId});</insert>
</mapper>
3、模拟场景(50个线程抢购30件商品,还可以自行使用其它的方式实现模拟场景哦)
单例下获取SqlSessionFactory
public class MybatisFactory {private static SqlSessionFactory sqlSessionFactory = null;public static SqlSessionFactory getSqlSessionFactory() {if(sqlSessionFactory == null) {synchronized(SqlSessionFactory.class) {if(sqlSessionFactory == null) {InputStream is = MybatisFactory.class.getResourceAsStream("/mybatis/mybatis-config.xml");sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);}}}return sqlSessionFactory;}
}
执行对象
public class Execute implements Runnable {@Overridepublic void run() {SqlSessionFactory sqlSessionFactory = MybatisFactory.getSqlSessionFactory();SqlSession sqlSession = sqlSessionFactory.openSession(TransactionIsolationLevel.READ_COMMITTED);ProductDao productDao = sql
更多推荐
实践检验乐观锁与悲观锁
发布评论