我正在经历这个。在事务中,数据库本身被阻止而不是单个记录。
这是我的代码段。
代码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正常工作的好策略!
答案 0 :(得分:0)
阐述我们在评论中写的内容:
ActiveRecord事务是每个数据库的连接,而不是每个模型的连接。
https://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html
在开发环境中,Sqlite3无法支持对数据库的concurrent modification。