Rails在事务中,为什么整个数据库都被锁定而不是单个记录?

时间:2019-03-14 02:47:23

标签: ruby-on-rails transactions locking

我正在经历这个。在事务中,数据库本身被阻止而不是单个记录。

这是我的代码段。

代码1)

public async Task<ActionResult> CallAgent2(string agentId)
{
    var call = await _callsRepository.FindByAgentIdAsync(agentId);
    var conferences = ConferenceResource.Read(
        friendlyName: conferenceId,
        status: ConferenceResource.StatusEnum.InProgress
    );
    var conference = conferences[0];
    var participant = ParticipantResource.Update(
        pathConferenceSid: conference.Sid,
        pathCallSid: call.ConferenceId,
        hold: true,
        holdUrl: new System.Uri("http://twimlets.com/holdmusic?Bucket=com.twilio.music.classical")
    );

    var callBackUrl = GetConnectConfereceUrlForAgent(agentId, call.ConferenceId);
    _callCreator.CallAgent("agent2", callBackUrl);
    return new EmptyResult();
}

代码2)

SELECT
    e.date,
    e.event,
    (SELECT MAX(f1) FROM time t
     WHERE t.date_time BETWEEN e.date AND DATE_ADD(e.date, INTERVAL 2 DAY)) AS f1_max,
    (SELECT MAX(f2) FROM time t
     WHERE t.date_time BETWEEN e.date AND DATE_ADD(e.date, INTERVAL 2 DAY)) AS f2_max
FROM event e
ORDER BY
    e.date;

我在console1中执行了code1,并在另一个终端中打开了console2中执行了code2。显然,有两个控制台在本地共享数据库。

代码2抛出了类似的错误

lesson = Lesson.last
ActiveRecord::Base.transaction do
lesson.start_time = Time.now
  lesson.save
  sleep(10.seconds)
  raise "let's roll back lesson!!"
end

我假设代码1会因为出现异常而阻止修改教训(Lesson.last)。效果很好,但是符合我的期望的是代码2不会更新该课程(Lesson.first)。

如果这是本质(阻塞整个数据库,而不是单个记录),那么复杂的业务逻辑将最终由于事务的中断而受到影响。

有点好奇!什么是允许代码2正常工作的好策略!

1 个答案:

答案 0 :(得分:0)

阐述我们在评论中写的内容:

  

ActiveRecord事务是每个数据库的连接,而不是每个模型的连接。

https://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html

在开发环境中,Sqlite3无法支持对数据库的concurrent modification