-- 流水号自增表创建 DROP TABLE IF EXISTS code_date_sequence; CREATE TABLE code_date_sequence ( code_date VARCHAR(255) not null comment '日期字符串yyMMdd格式', code_type varchar(255) not NULL COMMENT '业务类型 通常是生成业务序号的前缀', sequence_no BIGINT not NULL COMMENT '序列号', UNIQUE KEY PK_date_code (code_date,code_type) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='序列号增长表'; -- 查询函数创建 DROP FUNCTION IF EXISTS getCodeDateNumber; CREATE FUNCTION getCodeDateNumber(codeType VARCHAR(255),codeDate VARCHAR(255),startValue INTEGER(11)) RETURNS bigint(20) BEGIN if startValue is null then set startValue = 1; end if; set @sn = startValue; INSERT INTO code_date_sequence (code_date,code_type,sequence_no) VALUES (codeDate,codeType,startValue) ON DUPLICATE KEY UPDATE sequence_no=@sn:=sequence_no+1; RETURN(@sn); END;
@Service public class GeneratorBiz implements IGeneratorBiz { private static final Logger logger = LoggerFactory.getLogger(GeneratorBiz.class); private static final String prefix0 = "00"; @Resource private CodeDateMybatisDao codeDateMybatisDao; @Override @Transactional(propagation = Propagation.REQUIRES_NEW) public String generatorStandardCode (String standardType) { String codeDate = DateUtil.format(new Date(), DateUtil.DATE_TIME_FORMAT_YMD); int suffixLength = 3; String result = null; String number = generatorSerialNumber(codeDate, standardType); if (StringUtils.isNotBlank(number)) { result = StringUtils.right(prefix0+number, suffixLength); if(number.length()>suffixLength){ result = number; } result = standardType + codeDate + result; } return result; } @Override @Transactional(propagation = Propagation.REQUIRES_NEW) public String generatorTaskCode (String standardCode, String warehouseCode) { String codeDate = DateUtil.format(new Date(), "MMdd"); int suffixLength = 2; String result = null; String codeType = standardCode + "-" + warehouseCode; String number = generatorSerialNumber(codeDate, codeType); if (StringUtils.isNotBlank(number)) { result = StringUtils.right(prefix0+number, suffixLength); if(number.length()>suffixLength){ result = number; } result = codeType + "-" + codeDate + "-" + result; } return result; } private String generatorSerialNumber(String codeDate, String codeType) { Map<String, Object> map = new HashMap<String, Object>(); map.put("codeDate", codeDate); map.put("codeType", codeType); codeDateMybatisDao.insertOnDuplicate(map); Integer number = codeDateMybatisDao.getCodeDateNumber(map); logger.info(DateUtil.format(new Date()) + ",codeDate:" + codeDate + ",codeType:" + codeType + ",number" + number + ",threadId" + Thread.currentThread().getId()); return number != null ? number.toString() : null; }
@MyBatisRepository public interface CodeDateMybatisDao { public Integer getCodeDateNumber(Map<String,Object> paramMap); public void insertOnDuplicate(Map<String,Object> paramMap); }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace必须指向Dao接口 --> <mapper namespace="com.sf.wop.qms.dao.mybatis.CodeDateMybatisDao"> <!-- 查询生成流水 --> <select id="getCodeDateNumber" parameterType="map" resultType="Integer"> select sequence_no from tb_qms_code_date_sequence where (code_date,code_type) in ((#{codeDate},#{codeType})) </select> <!-- 使用行级锁保证拿到的序号唯一 --> <insert id="insertOnDuplicate" parameterType="map"> INSERT INTO tb_qms_code_date_sequence (code_date,code_type,sequence_no) VALUES (#{codeDate},#{codeType},1) ON DUPLICATE KEY UPDATE sequence_no=sequence_no+1 </insert> </mapper>
相关推荐
行级锁的实例
MySQL数据库在处理并发操作时,为了保证数据的一致性和完整性,使用了不同的锁机制,包括行级锁、表级锁和页级锁。这三种锁的粒度不同,各有优缺点,适用于不同的场景。 行级锁是MySQL中最细粒度的锁,仅锁定操作的...
MySQL中的锁机制主要分为行级锁、表级锁和页级锁,这三种锁的粒度不同,分别适用于不同的并发场景。 行级锁是MySQL中最细粒度的锁,只针对当前操作的行进行锁定。行级锁分为共享锁(读锁)和排他锁(写锁),它能...
本文将深入探讨标题和描述中提及的各种锁,包括乐观锁、悲观锁、分布式锁、可重入锁、互斥锁、读写锁、分段锁、类锁以及行级锁。 1. **乐观锁**:乐观锁假设多线程环境中的冲突较少,所以在读取数据时不加锁,只有...
数据库系统通常采用两种锁的粒度:行级锁和表级锁。行级锁只锁定操作的数据行,提高了并发性,但在处理大量数据时可能导致锁竞争激烈。相反,表级锁一次性锁定整个表,降低了并发性能,但减少了锁的管理开销。 在...
在多用户环境中,为了保证数据的一致性和完整性,MySQL 提供了多种锁定机制,包括全局锁、表级锁和行级锁。这些锁机制是数据库事务处理中的核心组成部分,下面我们将详细探讨这些锁的特性和应用场景。 1. **全局锁...
Oracle数据库的锁机制是其实现高性能、高可用性和高安全性的基石之一。通过对DML锁、DDL锁以及内部锁和闩锁的理解,可以更好地设计和优化数据库应用程序,以应对复杂的业务场景和高并发访问需求。掌握Oracle数据库的...
例如,S锁与S锁、RS锁与RS锁、RX锁与RX锁之间是兼容的,但S锁与X锁、RS锁与X锁、RX锁与X锁之间不兼容。这些规则有助于开发者设计出高效且安全的并发处理策略。 在处理并发问题时,应谨慎使用锁,避免出现死锁情况,...
数据库锁是一种确保数据库数据一致性和完整性的机制,尤其在多用户同时对数据进行读写操作时,锁能够避免数据访问冲突。锁机制是数据库管理系统(DBMS)中的核心功能之一,它需要高效且复杂地管理并发访问,以避免...
在Oracle数据库中,锁的实现是轻量级的,它将锁作为数据块的属性直接存储在数据块头部,这部分称为ITL(Intent To Lock),用于记录事务在数据块上的活动信息,以确保事务的一致性。Oracle数据库并不像某些系统那样...
MySQL的锁定机制是数据库管理中不可或缺的一部分,它用于控制多个并发事务对数据的访问,确保数据的一致性和完整性。...在设计数据库事务和查询时,应考虑锁的粒度和潜在的并发问题,以实现最佳的系统性能。
当一个事务中涉及的锁数量达到一定的阈值(锁升级门限)时,系统会自动将行级锁和页面锁升级为表级锁,以减少锁的数量,提高系统性能。这个过程是自动的,用户通常无需手动干预。 锁在SQL Server中有多种模式,每种...
总之,Oracle的行级锁是数据库并发控制的重要工具,通过细致地配置和使用,可以实现高效且安全的数据访问。理解并掌握SELECT...FOR UPDATE语句及其相关选项,可以帮助开发人员更好地控制并发,提高数据库应用的性能...
### 数据库锁机制详解 #### 一、数据库锁的基本概念 在并发环境下,数据库系统面临着多种潜在的数据一致性问题。为了确保数据的正确性与一致性,数据库管理系统(DBMS)引入了锁机制作为并发控制的核心手段。 ###...
数据库相关的笔记
锁的粒度决定了锁的作用范围,分为行级锁(TX锁)、表级锁(TM锁)和数据库级锁。行级锁,如TX锁,可以细分为X锁,只允许一个事务对特定行进行独占式访问。表级锁有共享锁(RS、RX)和排他锁(S、SRX、X),共享锁...
值得学习的MySQL行级锁、表级锁、页级锁详细介绍
本文内容 •软件环境 •简单演示 Oracle 数据库并发导致行级锁 本文简单演示针对表主键并发导致的行级锁。并发是两个以上的用户对同样的数据进行修改(包括插入、删除和修改)。锁的产生是因为并发。没有并发,就...