假设我有一个应用程序,该应用程序从Internet站点提取一些数据并将其添加到数据库中。该应用程序在多个实例中运行,每个实例都提取特定国家/地区的数据。
某些数据链接到名为rounds
的主表,该主表具有PK
和auto-increment
字段,我的疑问来自于此代码:
using (MySqlConnection connection = new DBConnection().Connect())
{
using (MySqlCommand command = new MySqlCommand())
{
command.Connection = connection;
command.CommandText = "INSERT IGNORE INTO competition_rounds (round_id, season_id, `name`)
VALUES (@round_id, @season_id, @round_name)";
command.Parameters.Add("@round_id", MySqlDbType.Int32).Value = round.Id;
command.Parameters.Add("@season_id", MySqlDbType.Int32).Value = round.seasonId;
command.Parameters.Add("@round_name", MySqlDbType.VarChar).Value = round.Name;
command.ExecuteNonQuery();
return Convert.ToInt32(command.LastInsertedId);
}
}
上面的代码向rounds
表中添加了新一轮,这很好用。但是,如果我有多个实例在运行,应用程序是否有可能在两个实例中激发相同的代码并为两个实例返回相同的ID?例如:
instance 1 -> fire round insert -> return 3
instance 2 -> fire round insert -> return 3
两个实例都在完全相同的时间执行了相同的方法。这种情况会发生吗?可以防止吗?我应该创建GUID还是组合的PK
?
答案 0 :(得分:1)
MySQL等数据库管理系统(DBMS)基于 ACID (原子性,一致性,隔离性,持久性)事务进行操作。这些事务按顺序全部或全部排定。因此,您不必担心并行事务。
也就是说,在多个应用程序实例中,您可能需要担心哪个事务首先处理 。即,应用程序实例A的用户A可以在用户A之后的某个时间发送插入消息A,而应用程序实例B的用户B可以发送消息插入B。即使UserA首先发送了请求,也可能由于网络延迟而可以先接收并按照B的顺序处理,然后按照A的顺序处理。
答案 1 :(得分:1)
客户端从OK_PACKET加载LastInsertedId
属性:
OK包从服务器发送到客户端以发出信号 成功完成命令。从MySQL 5.7.5开始,OK数据包是 也用于指示EOF,并且已弃用EOF数据包。
在服务器端,从documentation:
您可以检索最新自动生成的 带有LAST_INSERT_ID()SQL函数的AUTO_INCREMENT值或 mysql_insert_id()C API函数。这些功能是 特定于连接的,因此它们的返回值不受 另一个也正在执行插入操作的连接。
换句话说,(在任何受人尊敬的数据库系统中)都会考虑这种情况。
你会没事的。