再谈ActiveRecord、MySQL和transaction

再谈ActiveRecord、MySQL和transaction

[b]第一篇:ActiveRecord如何与MySQL交互[/b]

我们自定义的MyModel继承于ActiveRecord::Base类
[code]
MyModel < ActiveRecord::Base
MyModel.find_xxx -> find_by_sql -> connection.select_all(sql)
MyModel.create_xxx -> connection.insert(sql)
MyModel.update_xxx -> connection.update(sql)
MyModel.destroy -> connection.delete(sql)
[/code]
这个connection是什么东西?让我们一步步往下看

可以看到MyModel的一些方法都在base.rb里实现为connection对象相关的方法
如果我们使用的是MySQL数据库,则这里的connection为ActiveRecord::ConnectionAdapters::MysqlAdapter对象
这是在Rails初始化时做的:
[code]
environment.rb的Rails::Initializer.run -> initializer.rb的process方法 -> initializer.rb的initialize_database方法
-> ActiveRecord::Base.establish_connection(connenction_specification.rb里对ActiveRecord::Base添加该方法和connection方法)
-> mysql_adapter.rb的mysql_connection方法 -> mysql.rb的real_connect方法 -> TCPSocket::new/UNIXSocket::new
[/code]

而MysqlAdapter继承于AbstractAdapter,AbstractAdapter又include了DatabaseStatements所以:
[code]
MyModel < ActiveRecord::Base
MyModel.find_xxx -> find_by_sql -> DatabaseStatements.select_all(sql) -> MysqlAdapter.select(sql) -> MysqlAdapter.execute(sql) -> MysqlAdapter.@connection.query(sql)
MyModel.create_xxx -> MysqlAdapter.insert(sql) -> MysqlAdapter.execute(sql) -> MysqlAdapter.@connection.query(sql)
MyModel.update_xxx -> MysqlAdapter.update(sql) -> MysqlAdapter.execute(sql) -> MysqlAdapter.@connection.query(sql)
MyModel.destroy -> DatabaseStatements.delete(sql) -> MysqlAdapter.execute(sql) -> MysqlAdapter.@connection.query(sql)
[/code]

这里的MysqlAdapter.@connection在mysql_adapter.rb的mysql_connection方法里初始化了:
[code]
require_mysql
mysql = Mysql.init
mysql.ssl_set(config[:sslkey], config[:sslcert], config[:sslca], config[:sslcapath], config[:sslcipher]) if config[:sslkey]

ConnectionAdapters::MysqlAdapter.new(mysql, logger, [host, username, password, database, port, socket], config)
[/code]

继续追踪:
[code]
@connection.query(sql) -> real_query(sql) -> command(sql) -> Net.read/write -> socket.read/write
[/code]
至此,Rails自带的MySQL Adapter了解清楚了。

[b]第二篇:ActiveRecord对MySQL的事务封装[/b]
首先看看MySQL的事务控制(摘自MySQL5.1参考手册):
[quote]
START TRANSACTION或BEGIN语句可以开始一项新的事务
COMMIT可以提交当前事务,使变更成为永久变更
ROLLBACK可以回滚当前事务,取消其变更
SET AUTOCOMMIT语句可以禁用或启用默认的autocommit模式,用于当前连接
默认情况下,MySQL采用autocommit模式运行
这意味着,当您执行一个用于更新(修改)表的语句之后,MySQL立刻把更新存储到磁盘中
如果您正在使用一个事务安全型的存储引擎(如InnoDB, BDB或NDB簇),则您可以使用以下语句禁用autocommit模式:SET AUTOCOMMIT=0
通过把AUTOCOMMIT变量设置为零,禁用autocommit模式之后,您必须使用COMMIT把变更存储到磁盘中,或着如果您想要忽略从事务开始进行以来做出的变更,使用ROLLBACK
使用START TRANSACTION,autocommit仍然被禁用,直到您使用COMMIT或ROLLBACK结束事务为止。然后autocommit模式恢复到原来的状态
[/quote]

开始追踪:
[code]
# transactions.rb

def self.included(base)
base.extend(ClassMethods)

base.class_eval do
[:destroy, :save, :save!].each do |method|
alias_method_chain method, :transactions
end
end
end
[/code]
这就是Rails里所谓的“隐式事务”,给你安排好了
这表示ActiveRecord对save,save!和destroy方法都包上了事务,而create、update、delete等方法最终都是调用save、save!和destroy方法

追踪:
[code]
transactions.rb的transaction -> connection.transaction -> MysqlAdapter.transaction(没有) -> AbstractAdapter.transaciton(没有) -> DatabaseStatements.transaction
[/code]

看下database_statements.rb里的transaciton方法:
[code]
def transaction(start_db_transaction = true)
transaction_open = false
begin
if block_given?
if start_db_transaction
begin_db_transaction
transaction_open = true
end
yield
end
rescue Exception => database_transaction_rollback
if transaction_open
transaction_open = false
rollback_db_transaction
end
raise
end
ensure
commit_db_transaction if transaction_open
end
[/code]

马上又回到mysql_adapter.rb里对transaction打开、提交、回滚的实现:
[code]
def begin_db_transaction #:nodoc:
execute "BEGIN"
rescue Exception
# Transactions aren't supported
end

def commit_db_transaction #:nodoc:
execute "COMMIT"
rescue Exception
# Transactions aren't supported
end

def rollback_db_transaction #:nodoc:
execute "ROLLBACK"
rescue Exception
# Transactions aren't supported
end
[/code]
execute即Mysql.query,上面提到了。

那么为啥ActiveRecord的transaction不支持嵌套呢?
还是看transaction.rb:
[code]
def transaction(*objects, &block)
previous_handler = trap('TERM') { raise TransactionError, "Transaction aborted" }
increment_open_transactions

begin
unless objects.empty?
ActiveSupport::Deprecation.warn "Object transactions are deprecated and will be removed from Rails 2.0. See http://www.rubyonrails.org/deprecation for details.", caller
objects.each { |o| o.extend(Transaction::Simple) }
objects.each { |o| o.start_transaction }
end

result = connection.transaction(Thread.current['start_db_transaction'], &block)

objects.each { |o| o.commit_transaction }
return result
rescue Exception => object_transaction_rollback
objects.each { |o| o.abort_transaction }
raise
ensure
decrement_open_transactions
trap('TERM', previous_handler)
end
end

private
def increment_open_transactions #:nodoc:
open = Thread.current['open_transactions'] ||= 0
Thread.current['start_db_transaction'] = open.zero?
Thread.current['open_transactions'] = open + 1
end

def decrement_open_transactions #:nodoc:
Thread.current['open_transactions'] -= 1
end
[/code]
原来,Rails每次遇到调用transaction方法时,看看当前线程里open transaction的次数:
1, 如果有多次,则调用connection.transaction(false, &block)
2, 如果为零次,则调用connection.transaction(true, &block)
而database_statements.rb里的transaciton方法根据true or false参数来判断是否重复open transaction
这样,Rails遇到最外层的transaction打开后,就不会再打开内部的transaction了,这也是手动写多层嵌套transaction时只有最外层的起作用的原因

至此,Rails对transaction的封装了解清楚。
【23】OpenCV C++实战篇——张正友相机标定【相机标定原理、相机标定流程、标定结果评价、图像畸变矫正】 R是3×3的正交单位矩阵(即旋转矩阵),t为平移向量,R、t与摄像机无关,所以称这两个参数为摄像机的外参数(extrinsicparameter),可以理解为两个坐标原点之间的距离,因其受x,y,z三个方向上的分量共同控制,所以其具有三个自由度。R是3×3的正交单位矩阵(即旋转矩阵),t为平移向量,R、t与摄像机无关,所以称这两个参数为摄像机的外参数(extrinsicparameter),可以理解为两个坐标原点之间的距离,因其受x,y,z三个方向上的分量共同控制,所以其具有三个自由度。 阅读详情

相关推荐

别再只用串口助手了!用LabVIEW给STM32F103C8T6做个专属上位机(附完整源码)

本文详细介绍了如何利用LabVIEW为STM32F103C8T6开发定制化上位机,替代传统串口助手,实现高效数据交互。内容涵盖硬件架构设计、STM32固件优化、LabVIEW上位机开发技巧及工业级应用案例,特别适合需要实时数据采集与处理的工控场景。

weixin_42524762的博客 367

mysql activerecord_ActiveRecord::StatementInvalid (Mysql2::Error: Incorrect string value:

今天碰到一个相当棘手的问题,那就是ActiveRecord::StatementInvalid (Mysql2::Error: Incorrect string value 。本来在本地测试是没有任何问题的,但是一到服务器上就会出错,错误为:Mysql2::Error: Incorrect string value,经过分析发现是中文的问题。按照理论来说以前都没有出现过这样的情况,为什么这次会出...

weixin_30482027的博客 382

OpenClaw智能体应用第一集--飞书多智能体配置

本文介绍了智能体(Agent)的核心概念与配置实践。Agent作为独立作用域的"大脑",包含模型(认知引擎)、记忆系统(短期/长期记忆)、人设(角色定义)、工具(外部能力调用)、规划执行(任务拆解)、运行环境等核心要素。每个Agent拥有唯一agentId标识,通过accountId区分渠道账号,Binding机制实现消息路由。实践部分展示了通过命令行配置多个智能体(如writer)的过程,包括插件注册和工具加载。系统支持多Agent架构,可根据不同场景需求灵活配置专属智能体。

weixin_44626085的博客 1746

Active Record 设计模式原理及简单实现

转载自:http://blog.youkuaiyun.com/fanhengguang_php/article/details/54964490 概述 本文简要介绍Active Record 设计模式。Active Record 是一种数据访问设计模式,它可以帮助你实现数据对象Object到关系数据库的映射。 应用Active Record 时,每一个类的实例对象唯一对应一个数据库表的一行(一对一关系)...

glowd的专栏 1008

Tessent_StdcellLib

第二种为 Tessent Cell lib,既可用于功能仿真,也可以用于测试逻辑插入。lib包含了用于仿真的功能信息,也包含DFT cell属性。如何使用tessent工具将stdcell verilog 仿真模型转换为tessent自己的lib。运行后工具会生成一个atpg的lib文件,打开文件,找到一个带SI的DFF,只有功能描述。tessnt lib分为两种,第一种为ATBG lib,可以用于仿真;打开生成的lib文件,多了dft_cell_selection。第二部:编写attributes文件。

qq_40411444的博客 2134

MacOS Intel芯片实战:Docker Compose一键部署Dify全流程解析

本文详细解析了在搭载Intel芯片的MacOS系统上,使用Docker Compose一键部署开源LLM应用开发平台Dify的全流程。内容涵盖环境准备、Docker配置与镜像加速、代码拉取与配置初始化、服务启动与问题排查,以及访问验证与初步探索,旨在帮助开发者快速在本地搭建私有化AI应用开发环境。

ik678901234的博客 618

MyBatisPlus系列之ActiveRecord(活动记录)

上篇:MyBatisPlus系列之条件构造器 EntityWrapper 一、ActiveRecord(活动记录) 1、ActiveRecord概述 Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。 ActiveRecord 一直广受动态语言( PHP 、 Ruby 等)的喜爱,而 Java 作为准静态语言,对于 ActiveRecord 往往只能感叹其优雅,所以MP也在 AR 道路上进行了一定的探索 ..

weixin_39868387的博客 682

荒岛逃生游戏

正负表示逃生方向(正表示向右逃生,负表示向左逃生),绝对值表示战斗力,越左边的数字表示里左边港口越近,逃生方向相同的人永远不会发生决斗。- 如果左逃生者的战斗力大于右逃生者,则左逃生者获胜,减少其战斗力,并将右逃生者出栈。- 处理完所有输入后,统计仍在右逃生者栈和左逃生者栈中的战斗力,即可得到成功逃生的人数。- 如果左逃生者的战斗力小于右逃生者,则右逃生者获胜,减少其战斗力,左逃生者出局。- 向左逃生:从右逃生者栈中取出元素,与当前逃生者进行决斗。- 继续进行决斗,直到没有右逃生者或左逃生者的战斗力用尽。

面试高手的博客 2101

ActiveRecord简单介绍

转载地址 https://www.cnblogs.com/jayhou/p/9824232.html 一、ActiveRecord简单介绍 Active Record(简称AR),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。而MP也对AR有一定支持。 在MP中开启AR,仅需要实体类继承Model类并实现主键指定方法 复制代码 @TableName(“tbl_employee”) public class Employee extends Model{

syyYoung的博客 2698

open3d将某一时间序列下的彩色图和深度图批量转换成点云(python)

必备条件需要3D相机生成的彩色图及深度图,注意要将深度图与彩色图对齐(一般3D相机自带对齐算子),以及3D相机的彩色图内参(相机自带内参获取功能)。有了此彩色图、对齐后的深度图以及相机内参就能使用open3d生成彩色点云了.

吾名招财的博客 315

项目经理必看:如何建立高效的相关方沟通机制?

你是否遇到过这样的场景?客户突然说“这不是我要的”,开发团队抱怨“需求总变”,高层追问“进度滞后为什么不早说”?这些问题的根源往往是——相关方沟通机制失效。本文聚焦“如何建立高效沟通机制”,覆盖从识别相关方到持续优化的全流程,适用于IT、产品、工程等各类项目。本文将按“理解问题→拆解核心概念→掌握工具方法→实战落地→未来趋势”的逻辑展开,重点讲解“相关方分析矩阵”“沟通计划表”等实用工具,并用“组织生日派对”的案例贯穿全文,让抽象概念变得可感知。相关方识别:用“权力/利益矩阵”找对人(像派对邀请关键客人)

项目管理的博客 1295

MySQL事务(transaction) (有这篇就足够了..)

事务就是由单独单元的一个或多个sql语句组成,在这个单元中,每个sql语句都是相互依赖的。而整个单独单元是作为一个不可分割的整体存在,类似于物理当中的原子(一种不可分割的最小单位)。 往通俗的讲就是,事务就是一个整体,里面的内容要么都执行成功,要么都不成功。不可能存在部分执行成功而部分执行不成功的情况。

qq_56880706的博客 5万+

概率的接力:拆解大模型“预测下一个词“的底层逻辑

大模型的智能不在于它拥有了意识,而在于它用纯数学的架构,将人类语言的复杂结构压缩为可计算的向量轨迹与概率接力。当我们不再将其拟人化为"思考者",而是视作高维条件概率引擎时,才能真正驾驭它。预测下一个词,从来不是终点,而是起点。未来的核心竞争力,属于那些能洞察其统计本质、善用其模式生成能力,并以人类理性与事实为锚点的协作者。词元的轨迹终会止步于上下文窗口,但对技术底层的清醒认知,才是跨越幻觉、走向真实智能的基石。

AI浩 329

castle activerecord mysql_Castle ActiveRecord学习(六)数据验证

参考、来源:http://www.cnblogs.com/Terrylee/archive/2006/04/13/374173.htmlhttps://github.com/castleproject/ActiveRecord/blob/master/docs/validation-support.mdhttps://github.com/castleproject/ActiveRecordhtt...

weixin_30213477的博客 184

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

GitHub::DS完全指南:如何基于ActiveRecord连接高效操作SQL

GitHub::DS 是一套基于 ActiveRecord 连接的 Ruby SQL 工具库集合,为开发者提供了更简洁、安全的 SQL 操作体验。无论你是 Rails 新手还是经验丰富的开发者,这套工具都能帮助你更高效地处理数据库交互,减少重复代码并提升查询性能。 ## 为什么选择 GitHub::DS? 在 Ruby 开发中,ActiveRecord 虽然强大,但原生 SQL 操作往往显得繁

gitblog_00317的博客 370

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Sinatra ActiveRecord 终极指南:如何在 Sinatra 中快速集成数据库操作

想要在轻量级 Sinatra 框架中享受 Rails 级别的数据库操作体验吗?✨ **Sinatra ActiveRecord** 正是您需要的解决方案!这个强大的 gem 将 ActiveRecord ORM 无缝集成到 Sinatra 应用中,让您能够快速构建功能完整的数据库驱动应用,无需复杂的配置和繁琐的代码。 ## 🚀 为什么选择 Sinatra ActiveRecord? Sina

gitblog_00372的博客 917

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

rails mysql事务_Rails ActiveRecord 事务研究

一、使用事务的原因ActiveRecord::Base.transaction doVideo.first.destroy!zz = Video.lastzz.status = 5zz.save!raise Exceptionend可以看到上面的例子中,每个事务中均含有多个不同的model。在同一个事务中调用多个model对象是常见的行为,因为事务是和一个数据库连接绑定在一起的,而不是某个mode...

weixin_39860260的博客 298

Sinatra ActiveRecord 测试策略:如何编写可靠的数据库测试

在构建基于 Sinatra 和 ActiveRecord 的 Web 应用时,数据库测试是确保应用稳定性的关键环节。本文将为您揭示 Sinatra ActiveRecord 的完整测试策略,帮助您编写可靠、高效的数据库测试,让您的应用在数据层坚如磐石。🚀 ## 为什么数据库测试如此重要? 数据库是大多数 Web 应用的核心组件,它存储着用户数据、业务逻辑和系统状态。Sinatra Activ

gitblog_00479的博客 337

ActiveRecord通过Transaction来确保对数据库操作成功

在你使用Transcations API时,系统就是像在基础数据库内使用SQL BEGIN...COMMIT。 注意:基础数据库必须支持事务。对于MySQL这意味着使用InnoDB存储引擎。 每个“活动记录”对象都有一个...

ckmqixs43075的博客 191

什么是with_advisory_lock?彻底理解数据库级互斥锁的终极指南

with_advisory_lock是一款为ActiveRecord 7.2+提供数据库级互斥锁功能的Ruby gem,支持MySQL和PostgreSQL数据库,能够帮助开发者轻松实现跨主机的并发控制。通过使用数据库原生的 advisory lock 机制,该工具可以确保关键代码段在分布式环境中安全执行,避免并发冲突。 ## 为什么需要数据库级互斥锁? 在多进程或分布式系统中,传统的Ruby

gitblog_00256的博客 830

with_advisory_lock入门:5分钟快速实现跨主机并发控制

在分布式系统中,跨主机的并发控制一直是开发者面临的挑战。**with_advisory_lock** 作为一款专为 ActiveRecord 7.2+ 设计的 Ruby gem,通过数据库级别的 advisory lock( advisory lock)机制,帮助开发者轻松实现跨主机的互斥访问控制。无论是多服务器部署还是多进程协作,这款工具都能为你的应用提供可靠的并发保障。 ## 什么是Advi

gitblog_00608的博客 961

如何在Rails项目中集成with_advisory_lock?完整安装与配置教程

在Rails应用开发中,处理并发操作时常常需要确保数据一致性,**with_advisory_lock**作为ActiveRecord的 advisory locking 解决方案,能帮助开发者轻松实现分布式锁机制。本文将详细介绍如何在Rails项目中快速集成并使用这个强大的工具,避免并发场景下的数据冲突问题。 ## 📦 1. 安装with_advisory_lock gem包 ### 1.

gitblog_00195的博客 726

with_advisory_lock测试指南:如何确保分布式锁的可靠性

在分布式系统中,确保数据一致性是开发者面临的重要挑战。with_advisory_lock作为ActiveRecord的分布式锁解决方案,通过数据库 advisory lock 机制提供可靠的并发控制。本文将详细介绍如何系统测试with_advisory_lock的可靠性,帮助开发者验证分布式锁在各种场景下的表现。 ## 测试环境准备 ### 基础测试配置 with_advisory_loc

gitblog_01166的博客 384

with_advisory_lock核心功能解析:从基础用法到高级选项

**with_advisory_lock**是一个为ActiveRecord提供Advisory locking功能的Ruby库,它能够帮助开发者在多线程或分布式环境中安全地管理共享资源,避免并发冲突。本文将从基础用法到高级选项,全面解析这个强大工具的核心功能。 ## 一、什么是Advisory Locking? Advisory locking是一种由应用程序显式控制的锁定机制,与数据库隐式

gitblog_00215的博客 286

事务处理

数据库事务将一系列修改组合在一起,以一种方式要么完成所有修改,要么一个都不修 改。经典使用事实的例子是两个银行账户间的现金交易。基本逻辑很简单。 account1.deposit(100) account2.withdraw(100) 在Active Record 中,我们使用transaction()方法来执行一个块,这是一个特殊的数 据库事务处理的上下关联的段落。这个块的结尾,事务处...

ruby-j 173
上一篇: On Designing and Deploying Internet-Scale Services
下一篇: MySQL存储程序之创建和维护存储程序
hidetobj
博客等级 码龄19年 16粉丝 301原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值