<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
select for update 即排他鎖,排他鎖又稱為寫鎖,簡稱X鎖,顧名思義,排他鎖就是不能與其他鎖並存,如一個事務獲取了一個資料行的排他鎖,其他事務就不能再獲取該行的其他鎖,包括共用鎖和排他鎖,但是獲取排他鎖的事務是可以對資料就行讀取和修改。
作用:保證資料的一致性,為了在查詢時,避免其他使用者對該表進行插入,修改或刪除等操作,造成表資料的不一致性。
這裡只講述和排他鎖有關內容。
INFORMATION_SCHEMA 是mysql自帶的後設資料資料庫INNODB_TRX是MYSQL中事務和鎖相關的表INNODB_TRX表提供了當前INNODB引擎內每個事務的資訊(除唯讀事務外),包括當一個事務啟動,事務是否在等待一個鎖,以及正在執行的SQL語句。
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
這裡使用mysql資料庫為例。
-- ---------------------------- -- Table structure for config -- ---------------------------- DROP TABLE IF EXISTS `config`; CREATE TABLE `config` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `value` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `name-index`(`name`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of config -- ---------------------------- INSERT INTO `config` VALUES (1, 'result', 'false');
├─main │ ├─java │ │ └─com │ │ └─xy │ │ └─springboot │ │ │ Application.java │ │ ├─db │ │ │ ├─dao │ │ │ │ │ ConfigDao.java │ │ │ │ ├─impl │ │ │ │ │ ConfigDaoImpl.java │ │ │ │ └─mapper │ │ │ │ ConfigMapper.java │ │ │ └─entity │ │ │ Config.java │ │ └─runner │ │ ExclusiveLocksRunner.java │ └─resources │ │ application.properties │ └─Mapper └─ ConfigMapper.xml
引入mysql driver、lombok、mybatis-plus等依賴
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.5</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.xy</groupId> <artifactId>spring-boot</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-boot</name> <description>Demo project for Spring Boot</description> <properties> <java.version>11</java.version> </properties> <dependencies> <!-- 使用mybatis-plus 持久層框架 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!-- mysql 連線驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
Mapper對映xml檔案內容如下:ConfigMapper.xml
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.xy.springboot.db.dao.mapper.ConfigMapper"> <select id="getLockedConfig" resultType="com.xy.springboot.db.entity.Config"> SELECT * FROM CONFIG WHERE name = #{name} AND value = ${value} FOR UPDATE SKIP LOCKED </select> </mapper>
ConfigMapper.java 介面類
package com.xy.springboot.db.dao.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.xy.springboot.db.entity.Config; import org.apache.ibatis.annotations.Param; public interface ConfigMapper extends BaseMapper<Config> { Config getLockedConfig(@Param("name") String name, @Param("value") String value); }
ConfigDao.java 介面類及其實現類
package com.xy.springboot.db.dao; import com.baomidou.mybatisplus.extension.service.IService; import com.xy.springboot.db.entity.Config; /** * 設定類介面 */ public interface ConfigDao extends IService<Config> { /** * 通過名稱和value值,獲取增加排他鎖的設定 * @param name * @param value */ Config getLockedConfig(String name, String value); }
package com.xy.springboot.db.dao.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xy.springboot.db.dao.ConfigDao; import com.xy.springboot.db.dao.mapper.ConfigMapper; import com.xy.springboot.db.entity.Config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class ConfigDaoImpl extends ServiceImpl<ConfigMapper, Config> implements ConfigDao { private ConfigMapper configMapper; @Autowired public void setConfigMapper(ConfigMapper configMapper) { this.configMapper = configMapper; } @Override public Config getLockedConfig(String name, String value) { return configMapper.getLockedConfig(name, value); } }
Config.java 實體類
package com.xy.springboot.db.entity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Getter; import lombok.Setter; /** * 設定表實體類 */ @TableName("config") @Getter @Setter public class Config { private int id; private String name; private String value; }
package com.xy.springboot; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.transaction.annotation.EnableTransactionManagement; @MapperScan(basePackages = "com.xy.springboot.db.dao.mapper") @EnableTransactionManagement @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
ExclusiveLocksRunner 該類實現了ApplicationRunner介面,其含義是在SpringBoot工程啟動之後,執行的操作。該類必須注入到IOC容器中。
package com.xy.springboot.runner; import com.xy.springboot.db.dao.ConfigDao; import com.xy.springboot.db.entity.Config; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; /** * 排他鎖驗證 */ @Slf4j @Component public class ExclusiveLocksRunner implements ApplicationRunner { private static final String RESULT_KEY = "result"; private static final String RESULT = "false"; private ConfigDao configDao; @Autowired public void setConfigDao(ConfigDao configDao) { this.configDao = configDao; } @Transactional(rollbackFor = Exception.class) @Override public void run(ApplicationArguments args) throws Exception { Config lockedConfig = configDao.getLockedConfig(RESULT_KEY, RESULT); if (lockedConfig == null) { log.error("config is null。because config is locked."); return; } log.info("start doing"); lockedConfig.setValue("true"); configDao.updateById(lockedConfig); } }
疑問:
- ExclusiveLocksRunner類中run方法上的@Transactional 註解是否起作用?
- select…for update 是否有效?
- select…for update 加鎖之後,未釋放之前,再次加鎖時,返回的lockedConfig內容是什麼?
斷點位置:
Debug如圖所示,證明ExclusiveLocksRunner.java中run 方法上@Transcational 註解是有效的。
進入invokeWithinTransaction 呼叫事務方法繼續偵錯,
整個呼叫流程如下:建立事務——> 呼叫run方法 -> commit提交事務。
進入run方法:根據檢索條件查詢內容,並對其內容設定類排他鎖。
LOG資訊如下:
查詢mysql中是否存在對應的排他鎖資訊
-- 執行如下資訊,檢視是否存在Lock資訊 SELECT trx_id, trx_state, trx_started, trx_rows_locked FROM INFORMATION_SCHEMA.INNODB_TRX;
結果如下:
證明:資料庫中已經存在排他鎖資訊,證明該加鎖方式是OK的,並在大概在第2行。
在資料庫中,再次執行以下SQL,進行查詢,得到結果為null。證書排他鎖未釋放之前,再次枷鎖時,返回內容為null,因此select…for update 加鎖之後,未釋放之前,再次加鎖時,返回的lockedConfig內容時null。
到此這篇關於SELECT… FOR UPDATE 排他鎖的實現的文章就介紹到這了,更多相關SELECT… FOR UPDATE 排他鎖內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45