类:Mongo::Session
- 继承:
-
对象
- 对象
- Mongo::Session
- 扩展方式:
- 可转发
- 包括:
- ClusterTime::Consumer 、 Loggable 、 Retryable
- 定义于:
- lib/ Mongo/session.rb 、
lib/ Mongo/session/session_pool.rb、
lib/ Mongo/session/server_session.rb、
lib/ Mongo/session/server_session/dirtyable.rb
Overview
会话对象不是线程安全的。 应用程序一次只能使用来自一个线程或进程的会话。
一种逻辑会话,表示应用程序执行的以某种方式相关的一设立顺序操作。
在命名空间下定义
常量摘要折叠
- MISMATCHED_CLUSTER_ERROR_MSG =
错误消息,指示会话是从与当前使用会话的客户端具有不同集群的客户端端检索的。
'用于创建此会话的客户端配置与此不匹配' + ” (拥有此操作的客户端)。请仅使用此会话通过其父会话进行操作 + '客户端。'
- SESSION_ENDED_ERROR_MSG =
错误消息,描述会话无法使用,因为它已结束。
'此会话已结束,无法使用。请创建一个新的。'- SESSIONS_NOT_SUPPORTED =
已弃用。
描述服务器版本不支持会话的错误消息。
'连接的服务器不支持会话。'- NO_TRANSACTION_STATE =
上次操作与任何事务无关或尚未发生任何操作的会话状态。
:no_transaction- STARTING_TRANSACTION_STATE =
用户已启动ACID 事务但事务中尚未发生任何操作的会话状态。
:starting_transaction- TRANSACTION_IN_PROGRESS_STATE =
一种会话状态,在该状态下,ACID 事务已启动,并且至少发生了一个操作,但ACID 事务尚未提交或中止。
:transaction_in_progress- TRANSACTION_COMMITTED_STATE =
最后执行的操作是事务提交的会话状态。
:transaction_committed- TRANSACTION_ABORTED_STATE =
最后执行的操作为事务中止的会话状态。
:transaction_aborted- UNLABELED_WRITE_CONCERN_CodeS =
此常量是私有 API 的一部分。 应尽可能避免使用此常量,因为它将来可能会被删除或更改。
[ 79, # UnknownReplWriteConcern 100, # CannotSatisfyWriteConcern, ].冻结
Loggable中包含的常量
实例属性摘要折叠
-
#client ⇒ Client
只读
创建此会话的客户端。
- # cluster ⇒ 对象 只读
-
# operation_time ⇒ BSON::Timestamp
只读
此会话的最新optime 。
-
# options ⇒ 哈希
只读
此会话的选项。
-
#pinned_connection_global_id ⇒ Integer | nil
只读
private
此会话固定的连接全局 ID(如果有)。
-
#pinned_server ⇒ MongoDB Server | nil
只读
private
此会话固定到的服务器(应该是mongos)(如果有)。
-
#recovery_token ⇒ BSON::Document | nil
private
在此会话上执行的分片事务的恢复令牌(如果有)。
- # snapshot_timestamp ⇒ 对象 private
-
#with_transaction_deadline ⇒ Integer | nil
只读
private
当前ACID 事务的截止日期(如果有)。
ClusterTime::Consumer中包含的属性
实例方法摘要折叠
-
# abort_transaction (options = nil) ⇒ 对象
中止当前活动的ACID 事务,而不对数据库进行任何更改。
-
# aborting_transaction? ⇒ true | false
private
会话当前是否正在中止ACID 事务。
-
# add_autocommit! (命令)→ 哈希、BSON::Document
private
将自动提交字段添加到命令文档(如果适用)。
-
# add_start_transaction! (命令)→ 哈希、BSON::Document
private
将 startTransaction 字段添加到命令文档(如果适用)。
-
# add_txn_num! (命令)→ 哈希、BSON::Document
private
将事务编号添加到命令文档(如果适用)。
-
# add_txn_opts! (command, _read, context) ⇒ 哈希、 BSON::Document
private
添加事务选项(如果适用)。
-
# advance_operation_time (new_operation_time) =" BSON::Timestamp"
提前此会话的缓存 optime。
-
# commit_transaction (options = nil) ⇒ 对象
提交会话上当前活动的ACID 事务。
-
# committing_transaction? ⇒ true | false
private
会话当前是否正在提交ACID 事务。
-
# 脏! (mark = true) ⇒ 对象
将根本的服务器会话的脏状态设置为给定值。
-
# 脏? ⇒ true | false | false nil
private
根本的服务器会话是否为脏会话。
-
#end_session ⇒ nil
结束此会话。
-
#结束? ⇒ true, false
此会话是否已结束。
-
#显式? ⇒ true, false
此会话是否为显式会话(即 用户创建)。
-
#隐式? ⇒ true, false
此会话是否为隐式会话(不是用户创建的)。
-
# in_transaction? ⇒ true | false
会话当前是否处于ACID 事务中。
-
#initialize (server_session, 客户端, options = {}) ⇒ 会话
构造函数
private
初始化会话。
-
#inside_with_transaction? ⇒ Boolean
private
当前是否位于 with_transaction区块内。
-
#检查⇒ string
获取用于检查的格式化string 。
-
# Materialize_if_needed ⇒ 会话
private
如果尚未设立,则通过从会话池中检出会话来填充会话对象的 server_session。
- #物化? ⇒ 布尔 private
-
# next_txn_num ⇒ 整数
private
递增并返回下一个ACID 事务编号。
-
#pin_to_connection (connection_global_id, connection: nil) ⇒ 对象
private
将此会话固定到指定连接。
-
#pin_to_server (服务器) ⇒ 对象
private
将此会话固定到指定服务器,该服务器应该是mongos。
-
# 进程 (result) ="Operation::Result"
private
处理来自使用此会话的服务器的响应。
-
# retry_reads? ⇒ 布尔
private
是否可以根据现代可重试读取规范重试使用此会话执行的读取。
-
# retry_writes? ⇒ true, false
是否会重试使用此会话执行的写入。
-
# revert_to_starting_transaction! ⇒ 对象
private
将会话状态恢复为 STARTING_TRANSACTION_STATE。
-
# session_id ⇒ BSON::Document
如果会话尚未结束,则获取此会话的服务器会话 ID。
-
# snapshot? ⇒ true | false
是否为会话配置了快照读取。
-
# start_transaction (options = nil) ⇒ 对象
将此会话中的后续操作放入新ACID 事务中。
- # startup_transaction? ⇒ 布尔 private
-
# Suppress_read_write_concern! (命令)→ 哈希、 BSON::Document
private
如果不适用,请从命令中删除读关注和/或写关注。
-
# txn_num ⇒ 整数
获取当前ACID 事务编号。
-
# txn_options ⇒ 哈希
在此会话上。
-
# txn_read_preference ⇒ 哈希
获取会话将在当前活动ACID 事务中使用的读取偏好(read preference)。
-
# unpin (connection = nil) ⇒ 对象
private
如果此会话已固定,则从固定的服务器或连接中取消固定此会话。
-
# unpin_maybe (error, connection = nil) ⇒ 对象
private
如果会话已固定,并且指定的异常实例和会话的ACID 事务状态要求将其取消固定,请从固定的服务器或连接上取消固定此会话。
-
# update_state! ⇒ 对象
private
由于正在运行的(非提交和非中止)操作而更新会话状态。
-
# validate! (客户端)→ 会话
private
验证会话以供指定客户端使用。
-
# validate_read_preference! (命令)→ 对象
private
确保命令的读取偏好(read preference)是主节点 (primary node in the replica set)。
-
# with_transaction (options = nil) ⇒ 对象
执行ACID 事务中提供的区块,并根据需要重试。
ClusterTime::Consumer中包含的方法
Loggable中包含的方法
#log_debug 、 #log_error 、 #log_ Fatal 、 #log_info 、 #log_warn 、 #logger
Retryable 中包含的方法
#read_worker、#select_server、#with_overload_retry、#write_worker
构造函数详情
#initialize (server_session, client, options = {}) ⇒会话
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
客户端应使用 Client#start_session 开始会话。此构造函数仅供内部驱动程序使用。
初始化会话。
会话可以是显式会话,也可以是隐式会话。显式会话的生命周期由应用程序托管- 应用程序显式创建此类会话并显式结束此类会话。隐式会话由驱动程序自动创建,其生命周期由驱动程序托管。
创建隐式会话后,不能有与之关联的服务器会话。 当实际执行使用此会话的操作时,将从会话池中检出服务器会话。 创建显式会话时,它必须引用已分配的服务器会话。
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/ Mongo/session.rb', 第 80 行 def 初始化(server_session, 客户端, = {}) if [:因果一致性] && [:快照] 提高 ArgumentError, '不能在会话上同时设置 :causal_consistency 和 :snapshot 选项' end if [:implicit] 除非 server_session.nil? 提高 ArgumentError, “隐式会话在构造期间无法引用服务器会话” end elsif server_session.nil? 提高 ArgumentError, '显式会话必须在构造期间引用服务器会话' end @server_session = server_session = .dup # 隐式会话只需要集群和客户端选项(从不运行 # 个事务),因此请避免创建 Mongo::Client 克隆以防止 # 内存泄漏:直接使用原始客户端代替。 @client = [:implicit] ? 客户端 : 客户端.请使用(: admin) @cluster = @client.集群 @options = .dup.冻结 @cluster_time = nil @state = NO_TRANSACTION_STATE @with_transaction_deadline = nil @with_transaction_timeout_ms = nil @inside_with_transaction = false end |
实例属性详细信息
# 客户端 ⇒客户端(只读)
返回 创建此会话的客户端。
117 118 119 |
# File 'lib/ Mongo/session.rb', 第 117 行 def 客户端 @client end |
# cluster ⇒对象(只读)
119 120 121 |
# File 'lib/ Mongo/session.rb', 第 119 行 def 集群 @cluster end |
# operation_time =" BSON::Timestamp (只读)
返回此会话的最新看到的optime 。
130 131 132 |
# File 'lib/ Mongo/session.rb', 第 130 行 def operation_time @operation_time end |
# options ⇒哈希(只读)
返回 此会话的选项。
112 113 114 |
# File 'lib/ Mongo/session.rb', 第 112 行 def @options end |
#pinned_connection_global_id ⇒整数 | nil (只读)
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
返回此会话固定的连接全局 ID(如果有)。
281 282 283 |
# File 'lib/ Mongo/session.rb', 第 281 行 def pinned_connection_global_id @pinned_connection_global_id end |
#pinned_server ⇒ MongoDB Server | nil (只读)
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
返回此会话固定到的服务器(应该是mongos),如果有的话。
275 276 277 |
# File 'lib/ Mongo/session.rb', 第 275 行 def pinned_server @pinned_server end |
# Recovery_token ⇒ BSON::Document | nil
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
返回在此会话上执行的分片ACID 事务的恢复分片的(如果有)。
287 288 289 |
# File 'lib/ Mongo/session.rb', 第 287 行 def Recovery_token @recovery_token end |
# snapshot_timestamp ⇒对象
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
1270 1271 1272 |
# File 'lib/ Mongo/session.rb', 第 1270 行 def @snapshot_timestamp end |
#with_transaction_deadline ⇒ 整数 | nil (只读)
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
返回当前ACID 事务的截止日期(如果有)。
1274 1275 1276 |
# File 'lib/ Mongo/session.rb', 第 1274 行 def with_transaction_deadline @with_transaction_deadline end |
实例方法详细信息
# abort_transaction (options = nil) ⇒ 对象
中止当前活动的ACID 事务,而不对数据库进行任何更改。
803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 |
# File 'lib/ Mongo/session.rb', 第 803 行 def abort_transaction( = nil) 查询缓存.清除 check_if_ended! check_if_no_transaction! if inside_states?(TRANSACTION_COMMITTED_STATE) 提高 mongo::错误::InvalidTransactionOperation.new( mongo::错误::InvalidTransactionOperation.cannot_call_after_msg( :commitTransaction, :abortTransaction ) ) end if inside_states?(TRANSACTION_ABORTED_STATE) 提高 mongo::错误::InvalidTransactionOperation.new( mongo::错误::InvalidTransactionOperation.不能_call_tice_msg(:abortTransaction) ) end ||= {} 开始 除非 startup_transaction? @aborting_transaction = true 上下文 = 操作::上下文.new( 客户端: @client, 会话: self, operation_timeups: operation_timeups() ) write_with_retry([:write_concern], ending_transaction: true, 上下文: 上下文) do |连接, txn_num, 上下文| 操作 = 操作::命令.new( 选择器: { abortTransaction: 1 }, db_name: ' admin ', 会话: self, txn_num: txn_num ) 追踪器.trace_operation(操作, 上下文, op_name: 'abortTransaction') do 操作.execute_with_connection(连接, 上下文: 上下文) end 确保 取消固定 end end # 在更改状态之前完成ACID 事务跨度 追踪器.finish_transaction_span(self) @state = TRANSACTION_ABORTED_STATE 救援 mongo::错误::InvalidTransactionOperation 提高 救援 mongo::错误 追踪器.finish_transaction_span(self) @state = TRANSACTION_ABORTED_STATE 救援 例外 追踪器.finish_transaction_span(self) @state = TRANSACTION_ABORTED_STATE 提高 确保 @aborting_transaction = false end # 无官方返回值,但返回 true,以便在交互式 # 使用方法提示已成功。 true end |
# aborting_transaction? ⇒ true | false
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
返回 会话当前是否正在中止事务。
899 900 901 |
# File 'lib/ Mongo/session.rb', 第 899 行 def aborting_transaction? !!@aborting_transaction end |
# add_autocommit! (命令)→ 哈希 ( Hash ), BSON::Document
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
将自动提交字段添加到命令文档(如果适用)。
985 986 987 988 989 |
# File 'lib/ Mongo/session.rb', 第 985 行 def add_autocommit!(命令) 命令.点击 do |C| C[:autocommit] = false if in_transaction? end end |
# add_start_transaction! (命令)⇒哈希, BSON::Document
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
将 startTransaction 字段添加到命令文档(如果适用)。
1000 1001 1002 1003 1004 |
# File 'lib/ Mongo/session.rb', 第 1000 行 def add_start_transaction!(命令) 命令.点击 do |C| C[:startTransaction] = true if startup_transaction? end end |
# add_txn_num! (命令)⇒哈希, BSON::Document
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
将事务编号添加到命令文档(如果适用)。
1015 1016 1017 1018 1019 |
# File 'lib/ Mongo/session.rb', 第 1015 行 def add_txn_num!(命令) 命令.点击 do |C| C[:txnNumber] = BSON::Int64.new(@server_session.txn_num) if in_transaction? end end |
# add_txn_opts! (command, _read, context) ⇒ 哈希、BSON::Document
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
添加事务选项(如果适用)。
1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 |
# File 'lib/ Mongo/session.rb', 第 1030 行 def add_txn_opts!(命令, _read, 上下文) 命令.点击 do |C| # 应将读关注添加到启动事务的任何命令中。 if startup_transaction? # https://jira.mongodb.org/browse/SPEC- 1161 : 事务的 # 读关注会覆盖集合/数据库/客户端读关注, # 即使未设置事务的读关注。 # 这里的读关注是发送到服务器的关注,可能 # include afterClusterTime。 if rc = C[:readConcern] rc = rc.dup rc.删除(:level) end if txn_read_concern if rc rc.update(txn_read_concern) else rc = txn_read_concern.dup end end if rc.nil? || rc.空? C.删除(:readConcern) else C[:readConcern] = 选项::映射器.transform_values_to_strings(rc) end end # 我们需要将读关注级别作为string而不是符号发送。 C[:readConcern] = 选项::映射器.transform_values_to_strings(C[:readConcern]) if C[:readConcern] if C[:commitTransaction] && (max_time_ms = [:max_commit_time_ms]) C[:maxTimeMS] = max_time_ms end # 应将写关注(write concern)添加到任何 abortTransaction 或 commitTransaction 命令中。 if C[:abortTransaction] || C[:commitTransaction] if @already_committed wc = BSON::文档.new(C[:writeConcern] || txn_write_concern || {}) wc.合并!(w: : majority) wc[:wtimeout] ||= 10 _ 000 C[:writeConcern] = wc elsif txn_write_concern C[:writeConcern] ||= txn_write_concern end end # 非数字写关注 w 值需要作为string而不是符号发送。 if C[:writeConcern] && C[:writeConcern][:w] && C[:writeConcern][:w].is_a?(符号) C[:writeConcern][:w] = C[:writeConcern][:w].to_s end # Ignore wtimeout if csot C[:writeConcern]&。删除(:wtimeout) if 上下文&。csot? # 我们不得发送空(服务器默认)写关注(write concern)。 C.删除(:writeConcern) if C[:writeConcern] && C[:writeConcern].空? end end |
# advance_operation_time (new_operation_time) =" BSON::Timestamp "
提前此会话的缓存 optime。
1209 1210 1211 1212 1213 1214 1215 |
# File 'lib/ Mongo/session.rb', 第 1209 行 def advance_operation_time(new_operation_time) @operation_time = if @operation_time [ @operation_time, new_operation_time ].Max else new_operation_time end end |
# commit_transaction (options = nil) ⇒对象
提交会话上当前活动的ACID 事务。
717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 |
# File 'lib/ Mongo/session.rb', 第 717 行 def commit_transaction( = nil) 查询缓存.清除 check_if_ended! check_if_no_transaction! if inside_states?(TRANSACTION_ABORTED_STATE) 提高 mongo::错误::InvalidTransactionOperation.new( mongo::错误::InvalidTransactionOperation.cannot_call_after_msg( :abortTransaction, :commitTransaction ) ) end ||= {} 开始 # 如果 commitTransaction 被调用两次,则需要运行相同的提交 # 再次操作,因此我们将会话恢复到之前的状态。 if inside_states?(TRANSACTION_COMMITTED_STATE) @state = @last_commit_skipped ? STARTING_TRANSACTION_STATE : TRANSACTION_IN_PROGRESS_STATE @already_committed = true end if startup_transaction? @last_commit_skipped = true else @last_commit_skipped = false @committing_transaction = true write_concern = [:write_concern] || [:write_concern] write_concern = writeConcern.获取(write_concern) if write_concern && !write_concern.is_a?(writeConcern::Base) 上下文 = 操作::上下文.new( 客户端: @client, 会话: self, operation_timeups: operation_timeups() ) write_with_retry(write_concern, ending_transaction: true, 上下文: 上下文) do |连接, txn_num, 上下文| if 上下文.重试? && !上下文.overload_only_retry? if write_concern wco = write_concern..合并(merge)(w: : majority) wco[:wtimeout] ||= 10 _ 000 write_concern = writeConcern.获取(wco) else write_concern = writeConcern.获取(w: : majority, wtimeout: 10 _ 000) end end spec = { 选择器: { commitTransaction: 1 }, db_name: ' admin ', 会话: self, txn_num: txn_num, write_concern: write_concern, } 操作 = 操作::命令.new(spec) 追踪器.trace_operation(操作, 上下文, op_name: 'commitTransaction') do 操作.execute_with_connection(连接, 上下文: 上下文) end end end # 在更改状态之前完成ACID 事务跨度 追踪器.finish_transaction_span(self) 确保 @state = TRANSACTION_COMMITTED_STATE @committing_transaction = false end # 无官方返回值,但返回 true,以便在交互式 # 使用方法提示已成功。 true end |
# committing_transaction? ⇒ true | false
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
返回此会话当前是否正在提交事务。
891 892 893 |
# File 'lib/ Mongo/session.rb', 第 891 行 def committing_transaction? !!@committing_transaction end |
# 脏! (mark = true) ⇒ 对象
将根本的服务器会话的脏状态设置为给定值。 如果没有服务器会话,则不会执行任何操作。
139 140 141 |
# File 'lib/ Mongo/session.rb', 第 139 行 def dirty!(标记 = true) @server_session&。dirty!(标记) end |
# 脏? ⇒ true | false | false nil
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
返回根本的服务器会话是否为脏会话。 如果此会话不存在服务器会话,则返回 nil。
147 148 149 |
# File 'lib/ Mongo/session.rb', 第 147 行 def dirty? @server_session&。dirty? end |
# end_session ⇒ nil
结束此会话。
如果此会话中有正在进行的事务,则该事务将中止。 与此会话关联的服务器会话将返回到服务器会话池。 最后,此会话被标记为已结束并且不再可用。
如果此会话已结束,则此方法不执行任何操作。
请注意,此方法不会直接向此服务器发出 endSessions 命令,这与其名称所暗示的相反。
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
# File 'lib/ Mongo/session.rb', 第 374 行 def end_session if !结束? && @client if inside_states?(TRANSACTION_IN_PROGRESS_STATE) 开始 abort_transaction 救援 mongo::错误, 错误::AuthError end end # 释放任何固定连接(例如,在提交ACID 事务后 # 在负载均衡模式下)。 取消固定 if pinned_connection_global_id 集群.session_pool.checkin(@server_session) if @server_session end 确保 @server_session = nil @ended = true @client = nil end |
#结束? ⇒ true , false
此会话是否已结束。
244 245 246 |
# File 'lib/ Mongo/session.rb', 第 244 行 def 结束? !!@ended end |
#显式? ⇒ true , false
此会话是否为显式会话(即 用户创建)。
179 180 181 |
# File 'lib/ Mongo/session.rb', 第 179 行 def explicit? !隐式? end |
#隐式? ⇒ true , false
此会话是否为隐式会话(不是用户创建的)。
167 168 169 |
# File 'lib/ Mongo/session.rb', 第 167 行 def 隐式? @implicit ||= !!(@options.键?(:implicit) && @options[:implicit] == true) end |
# in_transaction? ⇒ true | false
会话当前是否处于ACID 事务中。
883 884 885 |
# File 'lib/ Mongo/session.rb', 第 883 行 def in_transaction? inside_states?(STARTING_TRANSACTION_STATE, TRANSACTION_IN_PROGRESS_STATE) end |
#inside_with_transaction? ⇒ Boolean
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
返回当前是否位于 with_transaction区块内。
1278 1279 1280 |
# File 'lib/ Mongo/session.rb', 第 1278 行 def inside_with_transaction? @inside_with_transaction end |
#检查⇒ string
获取用于检查的格式化string 。
352 353 354 |
# File 'lib/ Mongo/session.rb', 第 352 行 def 检查 " #<Mongo::Session: 0 x #{ object_id } session_id= #{ session_id } options= #{ @options } > " end |
# Materialize_if_needed ⇒会话
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
如果尚未设立,则通过从会话池中检出会话来填充会话对象的 server_session。
1223 1224 1225 1226 1227 1228 1229 1230 1231 |
# File 'lib/ Mongo/session.rb', 第 1223 行 def Materialize_if_needed 提高 错误::SessionEnded if 结束? return 除非 隐式? && !@server_session @server_session = 集群.session_pool.checkout self end |
#物化? ⇒布尔
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
1234 1235 1236 1237 1238 |
# File 'lib/ Mongo/session.rb', 第 1234 行 def 物化? 提高 错误::SessionEnded if 结束? !@server_session.nil? end |
# next_txn_num ⇒整数
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
递增并返回下一个ACID 事务编号。
1249 1250 1251 1252 1253 |
# File 'lib/ Mongo/session.rb', 第 1249 行 def next_txn_num 提高 错误::SessionEnded if 结束? @server_session.next_txn_num end |
#pin_to_connection (connection_global_id, connection: nil) ⇒ 对象
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
将此会话固定到指定连接。
此会话到。
925 926 927 928 929 930 |
# File 'lib/ Mongo/session.rb', 第 925 行 def pin_to_connection(connection_global_id, 连接: nil) 提高 ArgumentError, '无法固定到零连接 ID ' if connection_global_id.nil? @pinned_connection_global_id = connection_global_id @pinned_connection = 连接 end |
#pin_to_server (server) ⇒对象
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
将此会话固定到指定服务器,该服务器应该是mongos。
908 909 910 911 912 913 914 915 916 |
# File 'lib/ Mongo/session.rb', 第 908 行 def pin_to_server(server) 提高 ArgumentError, “无法固定到零服务器” if server.nil? if Lint.已启用? && !server.mongos? 提高 错误::LintError, “ 尝试将会话固定到 不是 mongos 的服务器 #{ server .summary } } ” end @pinned_server = server end |
# process (result) = "Operation::Result"
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
处理来自使用此会话的服务器的响应。
1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 |
# File 'lib/ Mongo/session.rb', 第 1183 行 def 处理(结果) 除非 隐式? set_operation_time(结果) if cluster_time_doc = 结果.cluster_time advance_cluster_time(cluster_time_doc) end end @server_session.set_last_use! if (doc = 结果.回复 && 结果.回复.文档.first) && doc[:recoveryToken] self.Recovery_token = doc[:recoveryToken] end 结果 end |
# retry_reads? ⇒布尔
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
是否可以根据现代可重试读取规范重试使用此会话执行的读取。
如果此方法返回 true,则应用程序已请求现代可重试读取。 如果为读取操作选择的服务器支持现代可重试读取,则将用于该特定操作。 如果为读取操作选择的服务器不支持现代可重试读取,则不会重试读取。
如果此方法返回 false,则应用程序已请求传统可重试读取。 无论客户端连接到的服务器的版本如何,都将使用传统的可重试读取逻辑。 读取重试次数由 :max_read_retries 客户端选项指定,默认为1 ,可以设置为0以禁用传统读取重试。
199 200 201 |
# File 'lib/ Mongo/session.rb', 第 199 行 def retry_reads? 客户端.[:retry_reads] != false end |
# retry_writes? ⇒ true , false
可重试写入仅适用于分片集群、副本集或负载均衡拓扑结构。
是否会重试使用此会话执行的写入。
214 215 216 |
# File 'lib/ Mongo/session.rb', 第 214 行 def retry_writes? !!客户端.[:retry_writes] && (集群.replica_set? || 集群.分片的? || 集群.load_balanced?) end |
#revert_to_starting_transaction! ⇒ 对象
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
将会话状态恢复为 STARTING_TRANSACTION_STATE。在重试ACID 事务中的第一个命令之前调用,以便在重试时保留 startTransaction: true。
1134 1135 1136 1137 1138 |
# File 'lib/ Mongo/session.rb', 第 1134 行 def revert_to_starting_transaction! return 除非 inside_states?(TRANSACTION_IN_PROGRESS_STATE) @state = STARTING_TRANSACTION_STATE end |
#session_id ⇒ BSON::Document
如果会话尚未结束,则获取此会话的服务器会话 ID。 如果会话已结束,则引发 Error::SessionEnded。
256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/ Mongo/session.rb', 第 256 行 def session_id 提高 错误::SessionEnded if 结束? # 显式会话始终有一个 session_id,因为在 # 必须提供服务器会话构建。 隐式会话 # 在物化之前不会有 session_id,因此调用 # session_id 可能会失败。 应用程序不应有机会 # 会出现此故障,因为隐式会话不应 # 可供应用程序访问,因为其生命周期被限制为 # 操作执行,完全由驱动程序完成。 提高 错误::SessionNotMaterialized 除非 物化? @server_session.session_id end |
# snapshot? ⇒ true | false
返回该会话是否配置为支持快照读取。
123 124 125 |
# File 'lib/ Mongo/session.rb', 第 123 行 def 快照? !![:快照] end |
# start_transaction (options = nil) ⇒对象
将此会话中的后续操作放入新ACID 事务中。
请注意,在调用 start_transaction 后执行操作之前,不会在服务器上启动事务。
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 |
# File 'lib/ Mongo/session.rb', 第 653 行 def start_transaction( = nil) check_transactions_supported! if Lint.validate_read_concern_option([:read_concern]) # # 在这里检测无效的读取偏好(read preference)会很方便,但是 # # 某些规范测试需要稍后检测无效的读取偏好。 # # 也许我们可以在 lint模式打开时执行此操作。 # 模式 = options[:read] && options[:read][: 模式].to_s # if 模式 && 模式 != ' 主节点 (primary node in the replica set)' #引发 Mongo::Error::InvalidTransactionOperation.new( # "ACID 事务中的读取偏好(read preference)必须是主节点 (primary node in the replica set)(requested: #{模式})" # ) # end end 提高 mongo::错误::SnapshotSessionTransactionProhibited if 快照? check_if_ended! if inside_states?(STARTING_TRANSACTION_STATE, TRANSACTION_IN_PROGRESS_STATE) 提高 mongo::错误::InvalidTransactionOperation.new( mongo::错误::InvalidTransactionOperation::TRANSACTION_ALREADY_IN_PROGRESS ) end 取消固定 next_txn_num @txn_options = (@options[:default_transaction_options] || {}).合并(merge)( || {}) if txn_write_concern && !writeConcern.获取(txn_write_concern).已确认? 提高 mongo::错误::InvalidTransactionOperation.new( mongo::错误::InvalidTransactionOperation::UNACKNOWLEDGED_WRITE_CONCERN ) end @state = STARTING_TRANSACTION_STATE @already_committed = false 追踪器.start_transaction_span(self) # 该方法没有显式返回值。 # 我们可以在此处返回 nil,但 true 向用户表明 # 操作成功。 这是供交互式使用的。 # 请注意,返回值没有记录。 true end |
# startup_transaction? ⇒布尔
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
871 872 873 |
# File 'lib/ Mongo/session.rb', 第 871 行 def startup_transaction? inside_states?(STARTING_TRANSACTION_STATE) end |
# Suppress_read_write_concern! (命令)⇒哈希, BSON::Document
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
如果不适用,请从命令中删除读关注和/或写关注。
1098 1099 1100 1101 1102 1103 1104 1105 |
# File 'lib/ Mongo/session.rb', 第 1098 行 def subsup_read_write_concern!(命令) 命令.点击 do |C| 来年 除非 in_transaction? C.删除(:readConcern) 除非 startup_transaction? C.删除(:writeConcern) 除非 C[:commitTransaction] || C[:abortTransaction] end end |
# txn_num ⇒整数
获取当前ACID 事务编号。
1263 1264 1265 1266 1267 |
# File 'lib/ Mongo/session.rb', 第 1263 行 def txn_num 提高 错误::SessionEnded if 结束? @server_session.txn_num end |
# txn_options ⇒哈希
在此会话上。
155 156 157 |
# File 'lib/ Mongo/session.rb', 第 155 行 def @txn_options or 提高 ArgumentError, '没有活动的ACID 事务' end |
# txn_read_preference ⇒哈希
获取会话将在当前活动ACID 事务中使用的读取偏好(read preference)。
这是带有下划线键的驱动程序风格的哈希。
229 230 231 232 233 234 |
# File 'lib/ Mongo/session.rb', 第 229 行 def txn_read_preference rp = [:read] || @client.read_preference mongo::Lint.validate_underscore_read_preference(rp) rp end |
# unpin (connection = nil) ⇒对象
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
如果此会话已固定,则从固定的服务器或连接中取消固定此会话。
938 939 940 941 942 943 944 945 946 947 948 949 950 951 |
# File 'lib/ Mongo/session.rb', 第 938 行 def 取消固定(连接 = nil) @pinned_server = nil @pinned_connection_global_id = nil conn = 连接 || @pinned_connection if conn conn.取消固定(事务) # 如果没有其他情况,才将连接重新签入连接池 # 仍然保持在其上(例如,打开的游标)。 除非 conn.已固定? conn.connection_pool.check_in(conn) end end @pinned_connection = nil end |
# unpin_maybe (error, connection = nil) ⇒对象
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
如果会话已固定,并且指定的异常实例和会话的ACID 事务状态要求将其取消固定,请从固定的服务器或连接上取消固定此会话。
异常实例应该已经设立了所有标签(客户端和服务器端生成的标签)。
964 965 966 967 968 969 970 971 972 973 974 |
# File 'lib/ Mongo/session.rb', 第 964 行 def unpin_maybe(错误, 连接 = nil) if !inside_states?(会话::NO_TRANSACTION_STATE) && 错误.标签?('TransientTransactionError') 取消固定(连接) end if committing_transaction? && 错误.标签?(' UnknownTransactionCommitResult ') 取消固定(连接) end end |
#update_state! ⇒ Object
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
由于正在运行的(非提交和非中止)操作而更新会话状态。
1144 1145 1146 1147 1148 1149 1150 1151 |
# File 'lib/ Mongo/session.rb', 第 1144 行 def update_state! 案例 @state when STARTING_TRANSACTION_STATE @state = TRANSACTION_IN_PROGRESS_STATE when TRANSACTION_COMMITTED_STATE, TRANSACTION_ABORTED_STATE @state = NO_TRANSACTION_STATE end end |
#validate!(client) ⇒ Session
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
验证会话以供指定客户端使用。
不得结束会话,并且必须由与要使用该会话的客户端具有相同集群的客户端创建该会话。
1166 1167 1168 1169 1170 |
# File 'lib/ Mongo/session.rb', 第 1166 行 def validate!(客户端) check_if_ended! check_matching_cluster!(客户端) self end |
# validate_read_preference! (命令)→对象
此方法是私有 API 的一部分。 您应尽可能避免使用此方法,因为它将来可能会被删除或更改。
确保命令的读取偏好(read preference)是主节点 (primary node in the replica set)。
1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 |
# File 'lib/ Mongo/session.rb', 第 1117 行 def validate_read_preference!(命令) return 除非 in_transaction? return 除非 命令[' $readPreference '] 模式 = 命令[' $readPreference ']['mode'] || 命令[' $readPreference '][:mode] return 除非 模式 && 模式 != ' primary ' 提高 mongo::错误::InvalidTransactionOperation.new( "事务中的读取偏好必须是主节点(已请求: #{ mode } ) " ) end |
# with_transaction (options = nil) ⇒对象
with_transaction 包含一个循环,因此如果 with_transaction 本身被置于一个循环中,其区块不应调用 next 或break 来控制外循环,因为这会影响 with_transaction 中的循环。 如果检测到这种情况,驱动程序将发出警告并中止事务。
执行ACID 事务中提供的区块,并根据需要重试。
返回区块的返回值。
确切的重试次数和执行时间是驱动程序的实现细节;提供的区块应该是幂等的,并且应该准备好被多次调用。 驱动程序可以在活动事务中重试提交命令,也可以重复事务并再次调用区块,具体取决于遇到的错误(如果有)。 另请注意,可能会对不同的服务器执行重试。
事务无法嵌套 - 如果在会话已有活动事务时调用此方法,则会引发 InvalidTransactionOperation。
区块引发的非派生自 Mongo::Error 的异常会停止处理、中止ACID 事务并从 with_transaction 中传播出去。 从 Mongo::Error 派生的异常可能会由 with_transaction 进行处理,从而导致进程重试。
目前,with_transaction 将重试提交并阻止调用,直到 with_transaction 自开始执行以来至少过去了120秒。 此超时不可配置,可能会在未来的驱动程序版本中更改。
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 |
# File 'lib/ Mongo/session.rb', 第 447 行 def with_transaction( = nil) @inside_with_transaction = true @with_transaction_timeout_ms = &。dig(:timeout_ms) || @options[:default_timeout_ms] || @client.timeout_ms @with_transaction_deadline = Compute_with_transaction_deadline() 截止日期 = if @with_transaction_deadline # 已启用 CSOT,因此我们有客户定义的截止日期。 @with_transaction_deadline else # CSOT 未启用,因此我们使用默认截止时间 120 秒。 Utils.monotic_time + 120 end transaction_in_progress = false transaction_attempt = 0 last_error = nil overload_error_count = 0 过载_遇到 = false 循环 do if transaction_attempt > 0 if 过载_遇到 延迟 = @client.retry_policy.backoff_delay(overload_error_count) if backoff_would_exceed_deadline?(截止日期, 延迟) make_timeout_error_from(last_error, ' CSOT 等待重试 withTransaction 超时时间已过 ') end 提高(last_error) 除非 @client.retry_policy.should_retry_overload?(overload_error_count, 延迟) 睡眠(延迟) else 退避 = backoff_seconds_for_retry(transaction_attempt) if backoff_would_exceed_deadline?(截止日期, 退避) make_timeout_error_from(last_error, ' CSOT 等待重试 withTransaction 超时时间已过 ') end 睡眠(退避) end end = {} [:write_concern] = [:write_concern] if start_transaction() transaction_in_progress = true transaction_attempt += 1 开始 rv = 产量 self 救援 例外 => e if inside_states?(STARTING_TRANSACTION_STATE, TRANSACTION_IN_PROGRESS_STATE) log_warn(" Aboring transaction due to #{ e . class } : #{ e } ") # CSOT:如果截止时间已过,请将其清除,以便 # abort_transaction 使用新的超时时间(而不是已过期的截止时间)。 # 如果截止时间尚未过期,请保持截止时间,以便 abort 使用剩余时间。 @with_transaction_deadline = nil if @with_transaction_deadline && period_expired?(截止日期) abort_transaction transaction_in_progress = false end if period_expired?(截止日期) transaction_in_progress = false make_timeout_error_from(e, ' CSOT 超时在 withTransaction回调期间已过期 ') end if e.is_a?(mongo::错误) && e.标签?('TransientTransactionError') last_error = e if e.标签?('SystemOverloadedError') 过载_遇到 = true overload_error_count += 1 elsif 过载_遇到 overload_error_count += 1 end 来年 end 提高 else if inside_states?(TRANSACTION_ABORTED_STATE, NO_TRANSACTION_STATE, TRANSACTION_COMMITTED_STATE) transaction_in_progress = false return rv end # CSOT: 如果在提交之前超时已过,则中止 #ACID 事务,并引发客户端超时错误。 if @with_transaction_deadline && period_expired?(截止日期) transaction_in_progress = false @with_transaction_deadline = nil abort_transaction 提高 mongo::错误::超时错误, ' 在提交ACID 事务之前,CSOT 超时已过期 ' end 开始 commit_transaction() transaction_in_progress = false return rv 救援 mongo::错误 => e if e.标签?(' UnknownTransactionCommitResult ') if period_expired?(截止日期) || (e.is_a?(错误::OperationFailure::家庭情况) && e.max_time_ms_expired?) transaction_in_progress = false 提高 除非 @with_transaction_timeout_ms && period_expired?(截止日期) make_timeout_error_from(e, ' CSOT 超时在 withTransaction提交期间已过期 ') end if e.标签?('SystemOverloadedError') 过载_遇到 = true overload_error_count += 1 elsif 过载_遇到 overload_error_count += 1 end if 过载_遇到 延迟 = @client.retry_policy.backoff_delay(overload_error_count) if backoff_would_exceed_deadline?(截止日期, 延迟) transaction_in_progress = false make_timeout_error_from(e, ' CSOT 超时在 withTransaction提交期间已过期 ') end 除非 @client.retry_policy.should_retry_overload?(overload_error_count, 延迟) transaction_in_progress = false 提高 end 睡眠(延迟) end = 案例 v = [:write_concern] when writeConcern::Base v. when nil {} else v end [:write_concern] = .合并(merge)(w: : majority) 重试 elsif e.标签?('TransientTransactionError') if Utils.monotic_time >= 截止日期 transaction_in_progress = false make_timeout_error_from(e, ' CSOT 超时在 withTransaction提交期间已过期 ') end last_error = e if e.标签?('SystemOverloadedError') 过载_遇到 = true overload_error_count += 1 elsif 过载_遇到 overload_error_count += 1 end @state = NO_TRANSACTION_STATE 来年 else transaction_in_progress = false 提高 end 救援 错误::AuthError transaction_in_progress = false 提高 end end end # 无官方返回值,但返回 true,以便在交互式 # 使用方法提示已成功。 true 确保 if transaction_in_progress log_warn(' with_transaction 回调打破了 with_transaction 循环,中止了事务') 开始 abort_transaction 救援 错误::OperationFailure::家庭情况, 错误::InvalidTransactionOperation end end @with_transaction_deadline = nil @with_transaction_timeout_ms = nil @inside_with_transaction = false end |