简体   繁体   English

Rails ActiveRecord连接会话

[英]Rails ActiveRecord connection session

I have the following piece of code in Rails 3.2 + mySQL application: 我在Rails 3.2 + mySQL应用程序中具有以下代码:

ActiveRecord::Base.connection.execute("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED")
ActiveRecord::Base.transaction do
              @book = ActiveRecord::Base.connection.execute("select * from books limit 1")
end

As far as I understand the first statement will result in the next ONE transaction within same session to be in "READ UNCOMMITTED" isolation and then isolation will return to default. 据我了解,第一条语句将导致同一会话中的下一个ONE事务处于“读取未提交”隔离状态,然后隔离将恢复为默认状态。

My questions are: Can I be sure that the transaction block will always be executed in the same session? 我的问题是:我可以确定事务块将始终在同一会话中执行吗? Also, can I be sure that no other transaction will take place in the same session between the first and the second statement? 另外,我可以确定在第一条语句和第二条语句之间的同一会话中不会发生其他事务吗?

I tried to Google for this topic, but as I am new to Rails I couldn't find any explanation that would make this clear to me. 我尝试使用Google搜索该主题,但是由于我是Rails的新手,所以找不到任何使我明白的解释。 Any help would be appreciated! 任何帮助,将不胜感激!

Thank you! 谢谢!

I think that all your questions can be answered with a "YES" . 我认为您所有的问题都可以回答“是” Even in Rails 3.2, the connections to the database are managed by the connection pool . 即使在Rails 3.2中,与数据库的连接也由连接池管理。 This pool ensures that each thread will have its own dedicated connection to the DB. 该池可确保每个线程将拥有自己的专用连接到数据库。 The pool assigns connections to threads based on their Thread IDs which are unique for each thread. 池根据线程的线程ID为每个线程分配唯一的连接。 Read the docs for more info. 阅读文档以获取更多信息。

So I think it should not be possible for two threads to share a connection and thus a MySQL session at the same time. 因此,我认为两个线程不可能同时共享一个连接,因此不能同时共享一个MySQL会话。 Also, it should be guaranteed that the transaction will always be called using the same connection (ie in the same session) as the isolation level setting code. 另外,应确保始终使用与隔离级别设置代码相同的连接(即,在同一会话中)调用事务。

By the way, if you used Rails 4 or higher, you could achieve the same behavior using the transaction method only. 顺便说一句,如果您使用的是Rails 4或更高版本,则只能使用transaction方法来实现相同的行为。 Unfortunately, setting isolation levels is not supported this way in Rails 3. So the following example actually won't work in your particular scenario: 不幸的是,Rails 3不支持以这种方式设置隔离级别。因此,以下示例实际上在您的特定情况下不起作用:

Book.transaction(:isolation => :read_uncommitted) do
  @book = Book.first
end
# => SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
#    BEGIN
#      SELECT  `books`.* FROM `books`  ORDER BY `books`.`id` ASC LIMIT 1
#    COMMIT

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM