C# 我需要在MySQL中使用事务对象吗
我需要创建一个MySQL表,并用Mono中的一些数据填充它。我正在使用以下代码执行此操作:C# 我需要在MySQL中使用事务对象吗,c#,mysql,transactions,mono,C#,Mysql,Transactions,Mono,我需要创建一个MySQL表,并用Mono中的一些数据填充它。我正在使用以下代码执行此操作: public class TestModel { protected IDbConnection dbcon; public TestModel() { string connectionString = "Server=localhost;" + "Database=cikdata;"
public class TestModel
{
protected IDbConnection dbcon;
public TestModel()
{
string connectionString = "Server=localhost;"
+ "Database=cikdata;"
+ "User ID=root;"
+ "Password=password;"
+ "Pooling=false";
dbcon = new MySqlConnection(connectionString);
dbcon.Open();
IDbCommand dbcmd = dbcon.CreateCommand();
// Create table
dbcmd.CommandText = "CREATE TABLE employee (firstname varchar(32), lastname varchar(32))";
dbcmd.ExecuteScalar();
// fill this table with some data
dbcmd.CommandText = "SELECT firstname, lastname FROM employee";
IDataReader reader = dbcmd.ExecuteReader();
while(reader.Read()) {
string FirstName = (string) reader["firstname"];
string LastName = (string) reader["lastname"];
Console.WriteLine("Name: " + FirstName + " " + LastName);
}
// clean up
reader.Close();
reader = null;
dbcmd.Dispose();
dbcmd = null;
}
~TestModel()
{
dbcon.Close();
dbcon = null;
}
}
我已经看到了很多在Mono中使用MySQL的例子,其中使用了IDbTransaction
。上面的代码在没有任何事务对象的情况下工作。我真的需要在代码中使用事务对象(和IDbTransaction.Commit
)吗
很抱歉问了这么一个新手问题。我主要是一名C++/PHP开发人员,对C#和Mono几乎没有经验。当您以一组单独的sql命令运行一个操作时,事务是一个好习惯 在这种情况下,这将取决于如果填充代码失败,是否希望回滚创建表 因此,您可以将其视为以下步骤
Start a transaction
Create the table
Insert some data
Commit transaction
如果没有显式事务,则存在不合法事务,因此如果在create table语句中附加一些insert语句,并调用ExcuteScalar,则会得到相同的效果
当您不想更改任何内容(如果其中任何部分失败)时,基本上使用启动事务/提交事务
或者,在执行“批处理”操作时,您不希望任何其他用户更改任何内容。当您以一组单独的sql命令运行一个操作时,事务是一个好习惯 在这种情况下,这将取决于如果填充代码失败,是否希望回滚创建表 因此,您可以将其视为以下步骤
Start a transaction
Create the table
Insert some data
Commit transaction
如果没有显式事务,则存在不合法事务,因此如果在create table语句中附加一些insert语句,并调用ExcuteScalar,则会得到相同的效果
当您不想更改任何内容(如果其中任何部分失败)时,基本上使用启动事务/提交事务
或者,在执行“批处理”操作时,您不希望任何其他用户更改任何内容。您绝对不应将该代码包含在事务中。如果你这样做,你只会让你自己或其他的代码读者感到困惑 这种情况下的原因是,
CREATE TABLE
在MySQL中导致了一个错误,因此在第一个命令(CREATE TABLE
)之后,您将已经提交了事务,其余的命令将在事务之外执行。而回滚或提交不会做任何事情
如果您尝试回滚创建表
mysql [localhost] {msandbox} (test) > start transaction;
Query OK, 0 rows affected (0.01 sec)
mysql [localhost] {msandbox} (test) > create table transtest(id int);
Query OK, 0 rows affected (0.32 sec)
mysql [localhost] {msandbox} (test) > rollback;
Query OK, 0 rows affected (0.02 sec)
mysql [localhost] {msandbox} (test) > select * from transtest;
Empty set (0.00 sec)
请注意,该表仍然存在……您绝对不应该在事务中包含该代码。如果你这样做,你只会让你自己或其他的代码读者感到困惑 这种情况下的原因是,
CREATE TABLE
在MySQL中导致了一个错误,因此在第一个命令(CREATE TABLE
)之后,您将已经提交了事务,其余的命令将在事务之外执行。而回滚或提交不会做任何事情
如果您尝试回滚创建表
mysql [localhost] {msandbox} (test) > start transaction;
Query OK, 0 rows affected (0.01 sec)
mysql [localhost] {msandbox} (test) > create table transtest(id int);
Query OK, 0 rows affected (0.32 sec)
mysql [localhost] {msandbox} (test) > rollback;
Query OK, 0 rows affected (0.02 sec)
mysql [localhost] {msandbox} (test) > select * from transtest;
Empty set (0.00 sec)
注意桌子是怎么还在那里的…理论上你是对的。然而,在MySQL中,CREATE TABLE永远不能在事务中,所以如果执行回滚操作,仍然会创建该表。我认为ExecuteScalar也是如此,因为在同一个事务中,没有任何东西可以围绕创建表和其他内容。我对此感到好奇,但更关心的是解释事务,而不是深入细节,也远离嵌套事务。MySQL没有嵌套事务:)不知道,尽管我不能说我感到惊讶,嵌套事务最大的效用是在复杂的存储过程中。理论上你是对的。然而,在MySQL中,CREATE TABLE永远不能在事务中,所以如果执行回滚操作,仍然会创建该表。我认为ExecuteScalar也是如此,因为在同一个事务中,没有任何东西可以围绕创建表和其他内容。我对此感到好奇,但更关心的是解释事务,而不是深入细节,也远离嵌套事务。MySQL没有嵌套事务:)不知道,尽管我不能说我感到惊讶,嵌套事务最大的实用程序是在复杂的存储过程中。所以我只需要在向表中插入一些数据时使用事务对象,对吗?这样,如果出现问题,我将能够回滚事务中的操作。如果您以“全部或无”为单位同时执行两个或多个insert/update/delete操作,则将其放入事务中。因此,只有在将某些数据插入表中时,我才需要使用事务对象,对吗?这样,如果出现问题,我将能够回滚事务中的操作。如果您以“全部或无”为单位同时执行两个或多个插入/更新/删除操作,则将其放入事务中。将IDisposable对象包装在“使用”块中,正如前面所说的,终结器在这里是个坏主意。谢谢,@skolima。我已经意识到为什么它如此糟糕。另外,当
TestModel
对象尚未删除时,是否需要保持与数据库的持久连接?对于特定的数据库查询/事务,打开
&关闭
连接可能会更好?打开新连接是一项代价高昂的操作,因此通常最好保留它,直到您真的不再需要它。将IDisposable对象包装在“使用”块中,正如前面所说的,终结器在这里是个坏主意。谢谢,@skolima。我已经意识到为什么它如此糟糕。另外,当TestModel
对象尚未删除时,是否需要保持与数据库的持久连接?对于特定的数据库查询/事务,打开
&关闭
连接可能会更好?打开新连接是一项代价高昂的操作,因此通常最好保留它,直到您真正不再需要它。