MySQL 表锁、行锁

打印 上一主题 下一主题

主题 537|帖子 537|积分 1611

一、表级锁定

读锁定:利用 LOCK TABLES 语句可以锁定一个或多个表格,直到当前会话竣事或利用 UNLOCK TABLES 解锁。比方:
  1. LOCK TABLES table_name READ;
复制代码
写锁定:利用 LOCK TABLES 语句并指定 WRITE 关键字可以锁定一个或多个表格,直到当前会话竣事或利用 UNLOCK TABLES 解锁。比方:
  1. LOCK TABLES table_name WRITE;
复制代码
二、行级锁定

在事务中利用 SELECT ... FOR UPDATE 语句可以锁定选定行,直到事务竣事为止。比方:
  1. START TRANSACTION;
  2. SELECT * FROM table_name WHERE condition FOR UPDATE;
  3. -- 对选定行进行操作
  4. COMMIT;
复制代码
大概利用 SELECT ... FOR SHARE 语句可以锁定选定行,但是允许其他会话也可以读取这些行。比方:
  1. START TRANSACTION;
  2. SELECT * FROM table_name WHERE condition FOR SHARE;
  3. -- 对选定行进行操作
  4. COMMIT;
复制代码
三、自动锁定

MySQL 在执行某些范例的操作时会自动举行锁定,比方在利用 INSERT, UPDATE, DELETE 等语句时会锁定受影响的行,直到事务竣事。 
无论利用哪种方法,肯定要鉴戒利用锁定,因为它可能会导致并发性能题目。发起只在须要时才利用锁定,并在锁定范围内尽量减少操作的时间。同时,肯定要在合适的时机释放锁定,以避免出现死锁或其他并发题目。
四、转账操作

在处置处罚转账等涉及到资金安全的操作时,确保数据的一致性和完整性非常重要。可以通过以下方法来实现转账过程中的锁定:
1、利用事务:在开始转账操作前,启动一个事务,并在事务中执行转账的相关操作。在事务中的全部操作要么全部乐成,要么全部失败,这可以确保转账的原子性。比方:
  1. START TRANSACTION;
  2. UPDATE accounts SET balance = balance - amount WHERE account_id = sender_id;
  3. UPDATE accounts SET balance = balance + amount WHERE account_id = receiver_id;
  4. COMMIT;
复制代码
2、行级锁定:在转账过程中,利用行级锁定来锁定涉及到的账户行,以防止其他会话同时修改这些行。比方,在开始事务后,可以利用 SELECT ... FOR UPDATE 来锁定相关账户行:
  1. START TRANSACTION;
  2. SELECT * FROM accounts WHERE account_id = sender_id FOR UPDATE;
  3. SELECT * FROM accounts WHERE account_id = receiver_id FOR UPDATE;
  4. -- 执行转账操作
  5. COMMIT;
复制代码
3、悲观锁(行锁):在开始转账操作前,利用 SELECT ... FOR UPDATE 来悲观地锁定涉及到的账户行,以确保在转账过程中不会有其他会话干扰。比方:
  1. START TRANSACTION;
  2. SELECT * FROM accounts WHERE account_id = sender_id FOR UPDATE;
  3. SELECT * FROM accounts WHERE account_id = receiver_id FOR UPDATE;
  4. -- 执行转账操作
  5. COMMIT;
复制代码
4、乐观锁(版本锁):在每个账户记录中添加一个版本号或时间戳,并在更新账户余额时查抄该版本号或时间戳,以确保没有其他会话同时修改了账户信息。如果发现冲突,可以选择回滚操作大概重试。比方:
  1. START TRANSACTION;
  2. SELECT * FROM accounts WHERE account_id = sender_id;
  3. -- 检查版本号或时间戳
  4. UPDATE accounts SET balance = balance - amount WHERE account_id = sender_id;
  5. SELECT * FROM accounts WHERE account_id = receiver_id;
  6. -- 检查版本号或时间戳
  7. UPDATE accounts SET balance = balance + amount WHERE account_id = receiver_id;
  8. COMMIT;
复制代码
四、Mybatis-jdbc

在利用 MyBatis 举行数据库操作时,你可以结合 MyBatis 的事务管理和数据库的行级锁定来实现转账过程中的数据锁定。
配置事务管理器:首先,确保你的 MyBatis 配置中配置了transactionManager type="JDBC"事务管理器,以便启用事务支持。
  1. <configuration>
  2.     <!-- 配置数据源等 -->
  3.    
  4.     <environments default="development">
  5.         <environment id="development">
  6.             <transactionManager type="JDBC"/>
  7.             <dataSource type="POOLED">
  8.                 <!-- 数据源配置 -->
  9.             </dataSource>
  10.         </environment>
  11.     </environments>
  12.     <!-- 映射器配置等 -->
  13. </configuration>
复制代码
编写转账操作的 Mapper 接口和 XML 映射文件:在 Mapper 接口中定义转账操作的方法,然后在 XML 映射文件中编写相应的 SQL 语句,包括行级锁定。
  1. public interface AccountMapper {
  2.     void transfer(@Param("senderId") Long senderId, @Param("receiverId") Long receiverId, @Param("amount") BigDecimal amount);
  3. }
复制代码
  1. <mapper namespace="com.example.mapper.AccountMapper">
  2.     <update id="transfer" parameterType="map">
  3.         START TRANSACTION;
  4.         SELECT * FROM accounts WHERE account_id = #{senderId} FOR UPDATE;
  5.         SELECT * FROM accounts WHERE account_id = #{receiverId} FOR UPDATE;
  6.         UPDATE accounts SET balance = balance - #{amount} WHERE account_id = #{senderId};
  7.         UPDATE accounts SET balance = balance + #{amount} WHERE account_id = #{receiverId};
  8.         COMMIT;
  9.     </update>
  10. </mapper>
复制代码
 
调用 Mapper 方法:在代码中调用 Mapper 接口中定义的方法执行转账操作。
  1. @Autowired
  2. private AccountMapper accountMapper;
  3. public void transfer(Long senderId, Long receiverId, BigDecimal amount) {
  4.     accountMapper.transfer(senderId, receiverId, amount);
  5. }
复制代码
MyBatis 中实现转账过程中的数据锁定。在执行转账操作时,MyBatis 会将相应的 SQL 语句发送到数据库,并在事务中举行处置处罚,同时利用行级锁定来确保数据的一致性和完整性。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

天空闲话

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表