我有一个允许我在MySQL数据库上运行查询的泛型类。
我在这个类中看到的唯一问题是它打开连接运行查询并关闭连接。
现在,我需要能够
START TRANSACTION;
SELECT ...
INSERT INTO table1...
INSERT INTO table2...
INSERT INTO table3...
COMMIT;
无法ROLLBACK;
是的,我需要一个事务,我需要确保所有查询都运行100%,或者我需要在重新开始之前回滚并更正错误。
如何修改我的课程以允许我处理上述步骤?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using MySql.Data.MySqlClient;
using System.Windows.Forms;
namespace RM
{
public class dbConnetion
{
//private OdbcConnection conn;
private static readonly string mServer = "localhost";
private static readonly string mDatabase = "my_db_name";
private static readonly string mUid = "my_db_user";
private static readonly string mPassword = "my_user_password";
private static readonly string mPort = "3306";
private string conn_string = String.Format("server={0};user={1};database={2};port={3};password={4};", mServer, mUid, mDatabase, mPort, mPassword);
public string SYSTEM_NAME { get; set; }
public dbConnetion()
{
Initilize_System_Settings();
}
// query the data base
public IEnumerable<T> getData<T>(string query, List<MySqlParameter> pars, Func<IDataRecord, T> transform)
{
using (var conn = new MySqlConnection(conn_string))
using (var cmd = new MySqlCommand(query, conn))
{
if (pars != null)
{
foreach (MySqlParameter p in pars)
{
cmd.Parameters.Add(p);
}
}
conn.Open();
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return transform(rdr);
}
}
conn.Close();
}
}
// query the data base
public T getValue<T>(string query, List<MySqlParameter> pars)
{
T value;
using (var conn = new MySqlConnection(conn_string))
using (var cmd = new MySqlCommand(query, conn))
{
if (pars != null)
{
foreach (MySqlParameter p in pars)
{
cmd.Parameters.Add(p);
}
}
try
{
conn.Open();
object rawValue = cmd.ExecuteScalar();
if (rawValue != null)
{
value = (T)Convert.ChangeType(rawValue, typeof(T));
}
else
{
value = default(T);
}
}
catch (Exception ex)
{
Common.Alert(ex.ToString(), "SQL Error");
value = default(T);
}
finally
{
conn.Close();
}
}
return value;
}
public bool processQuery(string strSQL, List<MySqlParameter> pars)
{
bool toReturn = true;
using (var conn = new MySqlConnection(this.conn_string))
using (var cmd = new MySqlCommand(strSQL, conn))
{
foreach (MySqlParameter param in pars)
{
cmd.Parameters.Add(param);
}
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (MySqlException ex)
{
Common.Alert(ex.ToString(), "SQL Error");
toReturn = false;
}
finally
{
conn.Close();
}
}
return toReturn;
}
}
}
我的第一个想法是在getData
方法中添加一个新参数,以便在有开放式交易时允许我不打开/关闭连接,例如
// query the data base
public IEnumerable<T> getData<T>(string query, List<MySqlParameter> pars, Func<IDataRecord, T> transform, bool inTransaction = false)
{
using (var conn = new MySqlConnection(conn_string))
using (var cmd = new MySqlCommand(query, conn))
{
if (pars != null)
{
foreach (MySqlParameter p in pars)
{
cmd.Parameters.Add(p);
}
}
if(! inTransaction){
conn.Open();
}
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return transform(rdr);
}
}
if(! inTransaction){
conn.Close();
}
}
}
但我认为由于using
声明
答案 0 :(得分:0)
trans = Conn.BeginTransaction();
trans.Commit();
trans.Rollback();
Cannot access SqlTransaction object to rollback in catch block
答案 1 :(得分:0)
您必须确定从何处开始和结束交易,
using (var conn = new MySqlConnection(conn_string))
{
var tx = conn.BeginTransaction();
try
{
using (var cmd1 = new MySqlCommand(query1, conn))
{
cmd1.Transaction = tx;
//do cmd 1 stuff here
}
using (var cmd2 = new MySqlCommand(query2, conn))
{
cmd2.Transaction = tx;
//do cmd 1 stuff here
}
//do other commands....
tx.Commit(); //or Rollback() based on results
}
catch (Exception ex)
{
tx.Rollback();
throw ex;
}
}