当前位置: 首页 > news >正文

网站中的滑动栏怎么做网站建设员工资

网站中的滑动栏怎么做,网站建设员工资,国外域名的网站,制作网页应该用哪个参考#xff1a;node支付宝支付及同步、异步通知、主动查询支付宝订单状态 以下容结合上述链接查看 1. 什么是数据库事务#xff1f; 1.1. 连续执行数据库操作 在支付成功后#xff0c;我们在自定义的paidSuccess里#xff0c;依次更新了订单状态和用户信息。也就说这里…参考node支付宝支付及同步、异步通知、主动查询支付宝订单状态 以下容结合上述链接查看 1. 什么是数据库事务 1.1. 连续执行数据库操作 在支付成功后我们在自定义的paidSuccess里依次更新了订单状态和用户信息。也就说这里先执行了更新订单表的SQL接着又执行了更新用户表的SQL。 但是大家想一想有没有可能。订单表更新成功了但因为某些原因导致用户表更新失败 比方说用户模型里用户组的效验写掉了1导致1存进不去。 又或者大会员有效期计算错误导致更新失败。 这样就可能订单状态更新成已支付了但用户却还是普通用户或者大会员有效期没有增加造成数据不一致。所以对于这种连续执行多条SQL语句的操作正确的做法是要加上事务。所谓数据库的事务 1.2.数据库事务基础概念 执行一组 SQL 操作这些操作必须全部成功执行或者全部不执行。如果其中任意一条SQL执行失败那就全部回滚(Rollback)撤销所有已经完成的操作确保数据的一致性和完整性。如果所有的操作都成功了才会提交(Commit)事务使所有更改永久生效。 1.3. SQL事务的使用 1.3.1.开启事务 (START TRANSACTION) -- 开始一个新的事务 START TRANSACTION;-- BEGIN简化写法 BEGIN;1.3.2. 连续连续执行多条 SQL 语句 -- 更新订单表 UPDATE Orders SET tradeNo 2024121322001495001404593598, paidAt 2024-12-13 12:35:31, status 1 WHERE id 5;现在用语句查询一下订单信息 -- 查询订单表 SELECT tradeNo, paidAt, status FROM Orders WHERE id 5;发现数据已经更新进去了。但是要注意因为现在数据库事务还没有提交所以这里并不是真正的保存进去了。 再继续更新用户表 -- 更新用户表 UPDATE Users SET role 1, membershipExpiredAt 2025年10月10日 WHERE id 2;语句里的日期还是写的错误的这是无法存进去的。提示我们错误信息了 1.3.3. 回滚 (ROLLBACK) 现在就造成了订单表更新了但是用户表更新失败两个表的数据不一致。碰到这种情况就可以使用回滚语句 -- 如果执行失败回滚所有操作 ROLLBACK;重新选中查询订单表的 SQL 语句运行一下发现订单表中刚才已经修改的数据被全部重置了 这样就不用担心两张表的数据不一致了。 1.3.4. 提交事务 (COMMIT) 如果所有语句都执行成功那要继续用COMMIT提交事务将数据永久的保存到数据库中。 将日期改为正确的时间 UPDATE Users SET role 1, membershipExpiredAt 2025-10-10 10:10:10 WHERE id 2; 1.3.5 完整代码 -- 开始一个新的事务也可用简写成 BEGIN二选一即可 START TRANSACTION;-- 连续执行多条SQL语句 -- 更新订单表 UPDATE Orders SET ... -- 更新用户表 UPDATE Users SET ...-- 如果执行失败回滚所有操作 ROLLBACK;-- 如果执行成功提交事务使所有更改成为永久性的 COMMIT; 1.4. 在 Node(ORM) 中使用数据库事务 第一种是非托管事务也就是必须手动执行提交和回滚。另一种是托管事务代码会自动处理提交和回滚。 1.4.1. 非托管事务 const { sequelize, User, Order } require(../models);/*** 支付成功后更新订单状态和会员信息* param outTradeNo* param tradeNo* param paidAt* returns {Promisevoid}*/ async function paidSuccess(outTradeNo, tradeNo, paidAt) {// 开启事务const t await Order.sequelize.transaction();try {// 查询当前订单在事务中const order await Order.findOne({where: { outTradeNo: outTradeNo },transaction: t,});// 对于状态已更新的订单直接返回。防止用户重复请求重复增加大会员有效期if (order.status 0) {return;}// 更新订单状态在事务中await order.update({tradeNo: tradeNo, // 流水号status: 1, // 订单状态已支付paymentMethod: 0, // 支付方式支付宝paidAt: paidAt, // 支付时间}, { transaction: t });// 查询订单对应的用户在事务中const user await User.findByPk(order.userId, { transaction: t });// 将用户组设置为大会员。可防止管理员创建订单并将用户组修改为大会员if (user.role 0) {user.role 1;}// 使用moment.js增加大会员有效期// user.membershipExpiredAt moment(user.membershipExpiredAt || new Date())// .add(order.membershipMonths, months)// .toDate();user.membershipExpiredAt 2025年10月10日;// 保存用户信息在事务中await user.save({ transaction: t });// 提交事务await t.commit();} catch (error) {// 回滚事务await t.rollback();// 将错误抛出让上层处理throw error;} } 顶部先引用一下。代码里开启了数据库事务。除了findOne是在where后面直接加上transaction: t之外。其他操作里都要添加第二个参数加上{ transaction: t }。关于这点文档中有说明我们给查询语句也加上了事务。这是因为查询语句也有可能出错。如果全都执行成功就提交事务。如果有执行失败的就回滚。注意最后这里要将错误抛出交给上层来处理。这样调用paidSuccess的路由里就会捕获到然后自动记录到错误日志里。 1.4.2. 托管事务 /*** 支付成功后更新订单状态和会员信息* param outTradeNo* param tradeNo* param paidAt* returns {Promisevoid}*/ async function paidSuccess(outTradeNo, tradeNo, paidAt) {try {// 开启事务await sequelize.transaction(async (t) {// 查询当前订单在事务中const order await Order.findOne({where: { outTradeNo: outTradeNo },transaction: t,});// 对于状态已更新的订单直接返回。防止用户重复请求重复增加大会员有效期if (order.status 0) {return;}// 更新订单状态在事务中await order.update({tradeNo: tradeNo, // 流水号status: 1, // 订单状态已支付paymentMethod: 0, // 支付方式支付宝paidAt: paidAt, // 支付时间}, { transaction: t });// 查询订单对应的用户在事务中const user await User.findByPk(order.userId, { transaction: t });// 将用户组设置为大会员。可防止管理员创建订单并将用户组修改为大会员if (user.role 0) {user.role 1;}// 使用moment.js增加大会员有效期// user.membershipExpiredAt moment(user.membershipExpiredAt || new Date())// .add(order.membershipMonths, months)// .toDate();user.membershipExpiredAt 2025年10月10日;// 保存用户信息在事务中await user.save({ transaction: t });});} catch (error) {// 将错误抛出让上层处理throw error; } } 非常简单在try里用sequelize.transaction包住所有代码。去掉commit和rollback。因为这种写法会自动提交和回滚。其他地方都和之前一样。 1.5. 总结一下 要一下执行多个数据库操作最好加上事务。要么全部执行成功要么就全部回滚。所以事务可以保障数据的完整性和一致性。 2. 数据库的乐观锁 2.1.多个事务修改同一条记录 2.1.1 库存问题 例如有个商品表里面有个库存字段。刚好这个商品现在只有1件了这时候两个人同时下单。但是因为事务还没有提交就会造成库存的错误判断。大家看这个表格 事务一A 下单事务二B 下单查询商品库存1 件查询商品库存1 件判断商品库存 0继续执行判断商品库存 0继续执行更新商品库存1 - 1 0 件更新商品库存1 - 1 0 件提交事务库存0 件提交事务库存0 件 最终结果是只有 1 件库存的商品却同时卖给了两个用户。这种情况特别是在高并发的秒杀项目里是最容易出现问题的。 2.1.2. 例二金融余额问题 事务一A 给 B 转账事务二C 给 A 汇款查询 A 的余额1000 元查询 A 的余额1000 元更新 A 的余额1000 - 500 500 元更新 A 的余额1000 200 1200 元提交事务余额500 元提交事务余额1200 元 因为事务二是后提交的所以最终数据库中保存的结果A 的余额就成了1200元。A 用户转账给别人的钱完全没有减少。这在金融项目中就是灾难了。 2.1.3. 例三更新订单和用户信息 操作步骤操作一操作二第一步查询订单状态0第二步查询订单状态0第三步判断状态为 0更新状态为1第四步判断状态为 0更新状态为1第五步增加大会员有效期第六步提交事务第七步再次增加大会员有效期第八步提交事务 。这就会造成用户的大会员时间重复增加两次 2.2.乐观锁实践 所谓乐观锁就是程序非常乐观的认为当前要操作的记录不会碰到其他人同时在操作。它允许多个事务同时对一条记录进行操作但是如果发现其他事务改变了数据它就报错提示用户重试。 最常见的做法是在数据库中增加版本号(version)或者时间戳(timestamp)字段。根据Sequelize 文档里的说明这里要用的是版本号(version)。 2.2.1 增加 version 字段 sequelize migration:create --name add-version-to-orders 打开迁移文件直接用讲义文档中的内容覆盖设置了版本号的默认值是0。 use strict;/** type {import(sequelize-cli).Migration} */ module.exports {async up (queryInterface, Sequelize) {await queryInterface.addColumn(Orders, version, {allowNull: false,defaultValue: 0,type: Sequelize.INTEGER.UNSIGNED});},async down (queryInterface, Sequelize) {await queryInterface.removeColumn(Orders, version);} }; 运行迁移命令 sequelize db:migrate 再打开模型文件models/order.js增加version字段相关的定义 Order.init({// ...version: {allowNull: false,type: DataTypes.INTEGER,defaultValue: 0},// ... }, {sequelize,modelName: Order, }); 2.2.3. 用 SQL 模拟更新订单 START TRANSACTION; SELECT id, version, status FROM Orders WHERE id 5;UPDATE Orders SET status 1, version version 1 WHERE id 5 and version 0; COMMIT; 接着我们开启两个数据库客户端 不太明确你说的“用上面的方式”具体所指你是希望我按照上述事务 A 和事务 B 的处理逻辑再举一个类似的例子吗还是有其他的想法呢以下我按照类似的逻辑以两个用户同时修改商品信息的事务场景为例再展示一遍 事务 A用户 1 修改商品信息事务 B用户 2 修改商品信息开启事务查询商品信息 输出status: 未上架、version: 0开启事务查询商品信息 输出status: 未上架、version: 0用 where version 0 作为条件更新为status: 已上架 version: 1提交事务用 where version 0 作为条件更新为status: 已上架 version: 1因为 version 被事务 A 改为 1 了所以找不到数据执行失败提交事务 2.3.在 Node 项目中实现乐观锁 2.3.1. 手动处理 打开routes/alipay.js顶部先做引用 Conflict 类专门用于表示 HTTP 409 状态码对应的错误也就是 “冲突” 错误 const { Conflict } require(http-errors); 增加一个函数实现延迟执行 此函数只是为了模拟 实际开发中不需要 /*** 实现延迟* param ms* returns {Promiseunknown}*/ function delay(ms) {return new Promise(resolve setTimeout(resolve, ms)); } 然后修改paidSuccess async function paidSuccess(outTradeNo, tradeNo, paidAt) {try {// 开启事务await sequelize.transaction(async (t) {// 查询当前订单在事务中const order await Order.findOne({where: {outTradeNo: outTradeNo}, transaction: t,});// 对于状态已更新的订单直接返回。防止用户重复请求重复增加大会员有效期if (order.status 0) {return;}await delay(5000); // 等待5秒// // 更新订单状态在事务中// await order.update({// tradeNo: tradeNo, // 流水号// status: 1, // 订单状态已支付// paymentMethod: 0, // 支付方式支付宝// paidAt: paidAt, // 支付时间// }, {transaction: t});// 更新订单状态在事务中包括版本号检查 // updatedRows 是数据库中受到影响的行数const [updatedRows] await Order.update({tradeNo: tradeNo, // 流水号status: 1, // 订单状态已支付paymentMethod: 0, // 支付方式支付宝paidAt: paidAt, // 支付时间version: order.version 1, // 增加版本号}, {where: {id: order.id, version: order.version, // 只更新版本号匹配的记录}, transaction: t,});// 如果没有更新数据提示错误if (updatedRows 0) {throw new Conflict(请求冲突您提交的数据已被修改请稍后重试。);}// 查询订单对应的用户在事务中const user await User.findByPk(order.userId, {transaction: t});// 将用户组设置为大会员。可防止管理员创建订单并将用户组修改为大会员if (user.role 0) {user.role 1;}// 使用moment.js增加大会员有效期user.membershipExpiredAt moment(user.membershipExpiredAt || new Date()).add(order.membershipMonths, months).toDate();// 保存用户信息在事务中await user.save({transaction: t});});} catch (error) {// 将错误抛出让上层处理throw error;} } 为了模拟并发请求增加了延迟 5 秒再执行。注意现在调用的是大写的Order模型而不是刚才查询小写的order对象。更新代码里对版本号也做了自增。查询条件里除了id以外还增加了之前查到的版本号。执行后会返回一个数组。数组的第一个元素表示数据库中受到影响的行数。如果数据库中受影响的行数为0表示数据没有更新成功就提示对应的错误信息。 测试 重置某条订单信息 UPDATE Orders SET tradeNo NULL, paidAt NULL,version 0, status 0 WHERE id 4; UPDATE Users SET role 0, membershipExpiredAt NULL WHERE id 2;Apifox 调用主动查询支付宝接口 因为我们写了等待 5 秒所以执行的时候会卡住。 快速的用数据库客户端执行下刚才测试用的 SQL 语句更新下订单状态并增加版本号。 START TRANSACTION; SELECT id, version, status FROM Orders WHERE id 4;UPDATE Orders SET status 1, version version 1 WHERE id 4 and version 0; COMMIT;继续等待 5 秒钟过去Apifox 中会出现错误提示。 这就是因为版本号已经被刚才数据库客户端修改了现在再执行更新的时候查不到对应的数据了所以没更新成功。 2.3.2. Sequelize 自动处理 根据官方文档中的说明在模型里设置version: true就可以自动实现乐观锁 我们现在来试试打开models/order.js。在最底下增加version: true。 Order.init({// ... }, {sequelize,modelName: Order,version: true, // 乐观锁 }); 回到路由里将顶部的引用删掉 // const { Conflict } require(http-errors);paidSuccess修改 async function paidSuccess(outTradeNo, tradeNo, paidAt) {try {// 开启事务await sequelize.transaction(async (t) {// 查询当前订单在事务中const order await Order.findOne({where: {outTradeNo: outTradeNo}, transaction: t,});// 对于状态已更新的订单直接返回。防止用户重复请求重复增加大会员有效期if (order.status 0) {return;}await delay(5000); // 等待5秒// // 更新订单状态在事务中await order.update({tradeNo: tradeNo, // 流水号status: 1, // 订单状态已支付paymentMethod: 0, // 支付方式支付宝paidAt: paidAt, // 支付时间}, {transaction: t});// 更新订单状态在事务中包括版本号检查 // updatedRows 是数据库中受到影响的行数 // const [updatedRows] await Order.update({ // tradeNo: tradeNo, // 流水号 // status: 1, // 订单状态已支付 // paymentMethod: 0, // 支付方式支付宝 // paidAt: paidAt, // 支付时间 // version: order.version 1, // 增加版本号 // }, { // where: { // id: order.id, version: order.version, // 只更新版本号匹配的记录 // }, transaction: t, // });// 如果没有更新数据提示错误if (updatedRows 0) {throw new Conflict(请求冲突您提交的数据已被修改请稍后重试。);}// 查询订单对应的用户在事务中const user await User.findByPk(order.userId, {transaction: t});// 将用户组设置为大会员。可防止管理员创建订单并将用户组修改为大会员if (user.role 0) {user.role 1;}// 使用moment.js增加大会员有效期user.membershipExpiredAt moment(user.membershipExpiredAt || new Date()).add(order.membershipMonths, months).toDate();// 保存用户信息在事务中await user.save({transaction: t});});} catch (error) {// 将错误抛出让上层处理throw error;} } utils/responses.js的错误响应中增加一个判断 function failure(res, error) {if (error.name SequelizeValidationError) { // Sequelize 验证错误// ...} else if(error.name SequelizeOptimisticLockError) {statusCode 409;errors 请求冲突您提交的数据已被修改请稍后重试。;} // ... }这是因为Sequelize自动实现的乐观锁如果出错了会响应SequelizeOptimisticLockError所以我们增加一个判断。 测试 重置某条订单信息 UPDATE Orders SET tradeNo NULL, paidAt NULL,version 0, status 0 WHERE id 4; UPDATE Users SET role 0, membershipExpiredAt NULL WHERE id 2;Apifox 调用主动查询支付宝接口 因为我们写了等待 5 秒所以执行的时候会卡住。 快速的用数据库客户端执行下刚才测试用的 SQL 语句更新下订单状态并增加版本号。 START TRANSACTION; SELECT id, version, status FROM Orders WHERE id 4;UPDATE Orders SET status 1, version version 1 WHERE id 4 and version 0; COMMIT;继续等待 5 秒钟过去Apifox 中会出现错误提示。 这就是因为版本号已经被刚才数据库客户端修改了现在再执行更新的时候查不到对应的数据了所以没更新成功。 2.3.3 测试完成后去掉delay函数 // await delay(5000); // 等待5秒2.4.总结一下 防止并发冲突为了防止多个操作同时修改数据库中的同一条记录可以使用锁机制。乐观锁假设冲突很少发生只有在发现冲突时才进行处理通常会提醒用户重试。原理是在数据库中增加一个版本号(version)字段在更新数据时检查版本号是否匹配若不匹配则提示用户重试。用户表的乐观锁我们演示了订单模型的乐观锁。对于用户表的更新可以用同样的方法增加version字段并且在模型中添加version: true。与事务的关系乐观锁与事务并没有直接关系但为了确保所有操作要么全部成功要么全部回滚两者经常结合使用以保证更好的一致性。适用场景乐观锁适用于并发较低、读多写少的场景。因为在这种情况下冲突发生的概率较小乐观锁可以减少不必要的锁定开销提高系统的并发性能。优缺点乐观锁的优点是系统并发性能较好因为不预先加锁减少了锁定带来的资源占用和等待时间缺点是需要实现重试逻辑可能影响用户体验。选择悲观锁的理由由于当前项目涉及支付对数据一致性和完整性要求极高而且提示用户重试会影响体验因此更适合使用悲观锁。 3.悲观锁 3.1悲观锁是什么 它认为数据随时都有可能被别人修改。所以只要在操作数据之前它就先把数据给锁起来。 -悲观锁里又分为共享锁和排它锁 共享锁就是大家共享的。一个资源允许同时存在多个共享锁。每个事务都可以读到这条记录。但是要想修改、删除必须等其他共享锁都释放后才能执行 3.1.1. 共享锁实践FOR SHARE 以订单表为例 重置一条数据 UPDATE Orders SET tradeNo NULL, paidAt NULL,version 0, status 0 WHERE id 4; UPDATE Users SET role 0, membershipExpiredAt NULL WHERE id 2;接着我们开启两个数据库客户端都运行相同的 SQL。 加上FOR SHARE就是共享锁 -- 开始一个新的事务 START TRANSACTION;-- 使用共享锁查询订单表 SELECT tradeNo, paidAt, status FROM Orders WHERE id 4 FOR SHARE;-- 更新订单表 UPDATE Orders SET tradeNo 2024121322001495001404593598, paidAt 2024-12-13 12:35:31, status 1 WHERE id 4;-- 提交事务 COMMIT; 在 A客户端先运行 开启事务 及 查询订单表sql 运行一下可以看到查到东西了。 在 B 客户端也运行前两条语句 因为加的是共享锁所以 B 客户端也能查到东西。 继续在 A 客户端运行更新订单表 注意了出现弹窗提示我们正在运行查询。 这就是刚说的一条数据可以有多个共享锁都可以查到东西。但是想要修改数据就必须得等其他所有的共享锁都释放了才能修改。 现在去 B 客户端了运行一下提交事务 可以看到提示信息马上就消失了执行成功了。这就是因为除了 A 客户端里的当前事务外其他事务的锁都释放了所以可以修改了。最后在 A 客户端里也点一下提交事务 事务 A事务 B开启事务查询数据并加共享锁查询成功开启事务查询数据并加共享锁查询成功修改数据发现有其他事务的共享锁等待释放中…提交事务释放了锁执行成功提交事务释放了锁 排它锁一个资源同一时间只允许存在一个排它锁。其他事务想要加锁必须得等待当前事务操作完成解锁后才行。所以在锁定期间其他事务不能读取更不能修改和删除了 3.1.2 排它锁实践 FOR UPDATE 以订单表为例 重置一条数据 UPDATE Orders SET tradeNo NULL, paidAt NULL,version 0, status 0 WHERE id 4; UPDATE Users SET role 0, membershipExpiredAt NULL WHERE id 2;接着我们开启两个数据库客户端都运行相同的 SQL。 加上FOR UPDATE就是排它锁 A 客户端 先运行前两句 -- 开始一个新的事务 START TRANSACTION;-- 使用共享锁查询订单表 SELECT tradeNo, paidAt, status FROM Orders WHERE id 4 FOR SHARE;-- 更新订单表 UPDATE Orders SET tradeNo 2024121322001495001404593598, paidAt 2024-12-13 12:35:31, status 1 WHERE id 4;-- 提交事务 COMMIT; B 客户端运行前两条语句(同上) 发现现在进行查询都会卡住这就是排它锁。A 对数据加上了排它锁后其他事务就不能再加排它锁了。不给你查更不给你修改、删除。必须等我执行完成后你再执行。 在 A 客户端点击提交事务B 客户端就马上可以执行成功了。接着在 B 客户端里也点一下提交事务将锁释放掉 以下是将你提供的内容转换为规范 Markdown 表格的形式这样在 CSDN 等平台通常能正常显示 事务 A事务 B开启事务查询数据并加排他锁查询成功开启事务查询数据并加排他锁发现有其他事务的排他锁等待释放中…提交事务释放了锁查询成功提交事务释放了锁 这里使用 br 来处理换行保证在支持 HTML 的 Markdown 渲染环境下能正确显示换行内容。如果在 CSDN 上还是显示异常可以尝试将整个表格代码放入代码块用三个反引号包裹中。 3.2.Node 项目中实现悲观锁 3.2.1.如果你跟着文章内容学习了共享锁 请去掉version: true 打开models/order.js Order.init({// ... }, {sequelize,modelName: Order,// version: true, // 乐观锁 }); 3.2.2. 共享锁的实现 lock: t.LOCK.SHARE 打开routes/alipay.js找到paidSuccess这里 const order await Order.findOne({where: { outTradeNo: outTradeNo },transaction: t,lock: t.LOCK.SHARE, // 增加共享锁 });// 其他...const user await User.findByPk(order.userId, {transaction: t,lock: t.LOCK.SHARE, // 增加共享锁 }); 非常简单的找到查询当前订单和查询当前用户这两个地方。增加上lock: t.LOCK.SHARE这就是共享锁了。 打开 Apifox调用下主动查询支付宝接口 然后观察终端中的 SQL 语句 3.2.3. 排它锁的实现 lock: t.LOCK.UPDATE const order await Order.findOne({where: { outTradeNo: outTradeNo },transaction: t,lock: t.LOCK.UPDATE, // 增加排它锁 });// 其他...const user await User.findByPk(order.userId, {transaction: t,lock: t.LOCK.UPDATE, // 增加排它锁 }); 先运行下 SQL重置一下数据库 UPDATE Orders SET tradeNo NULL, paidAt NULL,version 0, status 0 WHERE id 4; UPDATE Users SET role 0, membershipExpiredAt NULL WHERE id 2;再次调用 Apifox观察终端中运行的语句 根据官方文档的说明排它锁还可以简写成lock: true我们修改下代码 const order await Order.findOne({where: { outTradeNo: outTradeNo },transaction: t,lock: true, // 增加排它锁 });// 其他...const user await User.findByPk(order.userId, {transaction: t,lock: true, // 增加排它锁 }); 4.使用共享锁还是排它锁 那么到底是应该用共享锁还是排它锁呢在我们这个项目里订单状态从未支付变为已支付这是一个关键的业务操作必须确保一致性这里使用排它锁更为适合 这样当前事务在处理的时候其他事务就不能读取了更不能对这条记录进行修改操作。必须要等待当前事务执行完成后其他事务才能进行操作。这样就确保了在同一时间内只有一个事务可以操作当前数据保证了数据的一致性和完整性。 5.总结 5.1. 乐观锁与悲观锁的适用场景 乐观锁适用于读多写少的场景尤其是在高并发环境下冲突发生的概率较低时。它假设数据在大多数情况下不会被修改因此在提交更新之前不需要加锁而是在提交时通过版本号或时间戳检查是否有冲突发生。悲观锁适用于写操作频繁、冲突可能性较高的情况下。它假设经常发生冲突因此在执行任何可能引起冲突的操作前都会先加锁以确保数据的一致性和完整性。 5.2. 悲观锁的类型及其区别 共享锁S 锁或读锁 当前事务加共享锁后允许其他事务也对该资源加共享锁但禁止其他事务对该资源加排它锁。 在其他事务的共享锁没有释放之前当前事务和其他事务都禁止对该资源进行修改操作。排它锁X 锁或写锁 当前事务加排它锁后禁止其他事务对该资源加共享锁或排它锁。 排它锁确保只有一个事务可以对锁定的数据进行读取和修改。在排它锁未被释放之前其他事务不能对该资源加任何形式的锁。 5.3. 行锁与全表扫描的影响 加锁时的where条件里命中索引至关重要。只有通过索引条件来检索数据才能确保MySQL的InnoDB引擎能够精确地锁定当前记录这叫做行锁也就是只锁定一行记录。 但如果查询的数据无法命中索引MySQL不得不从头开始逐行扫描整个表直到找到对应的数据期间会将所有遇到的数据行全都加锁。这种情况虽然不是严格意义上的表锁但在效果上几乎等同于表锁。它会阻塞其他事务对这些行的操作显著降低并发性能。
http://www.w-s-a.com/news/592559/

相关文章:

  • 提供衡水网站建设中国石化工程建设有限公司邮政编码
  • 大芬地铁站附近做网站工业设计公司报价
  • 建设网站最强永年网站建设
  • 网站分站代理加盟wordpress国内工作室主题
  • 东营远见网站建设公司服装网站建设内容
  • 互助平台网站建设费用百度seo优化怎么做
  • lol英雄介绍网站模板工商局网上注册
  • 电商网站运营策划什么样的网站容易做seo
  • 网站备案需要什么流程怎么创建小程序卖东西
  • 陇西网站建设 室内设计持啊传媒企业推广
  • 连云港做网站制作首选公司如何让单位网站做防护
  • wordpress企业网站源码开发网站用什么工具做设计
  • 网站负责人不是法人seo神马网站推广器
  • 网站建设绩效考核方案wordpress支付宝付款
  • 高要区住房和城乡建设局网站如何网上注销自己的公司
  • 哪种技术做网站容易论文答辩图片做记录片的是哪个网站
  • 怎样在微信中做网站网站的备案号在哪
  • 返利淘网站怎么做wordpress htnl短代码
  • 网站 手机 appwordpress管理账户
  • 徐州网站建设 网站制作做招商网站的前景怎么样
  • 网站开发就业岗位鹧鸪哨网站1v1深度开发
  • 在线手机动画网站模板网站登录注册怎么做
  • 苏州品牌网站设计晋江论坛兔区是什么
  • 怎么利用代码做网站重庆网络营销网站建设销售
  • 用dw怎么做网站留言板百度举报网站
  • 成都微网站设计企业为什么要做网络营销推广
  • 双桥区网站制作企业网站一般内容包括哪些
  • 莆田外贸专业建站做app 需要先做网站吗
  • 网站怎么用北京口碑最好的装修公司
  • 潮州网站建设深圳微信分销网站设计