JavaからC#に移行しているので、Javaの機能よりもC#言語の機能の方が好きだと気づきましたが、この小さな問題があります。MySQL Connector / JおよびJDBCでは、アプリケーションの1つで、PreparedStatement
別のアプリケーションが開いているときに複数のを実行できると思います。たとえば、を返すクエリを実行でき、ResultSet
それResultSet
がまだ開いている間に、別のアプリケーションを開いて別のアプリケーションPreparedStatement
を取得できます。ResultSet
または、最初に取得したデータに基づいて更新を実行することもできますResultSet
(つまり、行のパスワード列にプレーンテキストのパスワードがあることに気付いたときに、ソルト値を挿入し、SHA512ハッシュでパスワード列を更新します)。
ただし、Connector / NETを使用すると、これを実行しようとすると、次のエラーが発生することに気付きました。
MySql.Data.MySqlClient.MySqlException: There is already an open DataReader associated with this Connection which must be closed first.
このエラーを修正する簡単な方法はありますか?MySQLから.NETへのブリッジの他の実装はありますか?1つのアプリケーションで多くのDB接続を作成したくはありませんが、(ThreadLocalのように)アプリケーションのスレッドごとに1つ作成したい場合があります。ThreadLocal DB接続は、2つの異なるメソッドで同時に2つのクエリを実行する場合に役立ちますが、明らかにこれら2つのコマンドを異なるスレッドに分離することはできず、余分なスレッドを作成したくありません。
ちなみに、これがコードそのものです。はい、リーダーを閉じた後、更新コードを下に移動できますが、同様の方法がたくさんあり、それらのいくつかはこれよりも修正が困難です。
MySqlConnection con = DatabaseConnection.GetConnection();
MySqlCommand cmd = con.CreateCommand();
cmd.CommandText = "SELECT `id`,`password`,`salt`,`pin`,`gender`,`birthday` FROM `accounts` WHERE `name` = '" + AccountName + "'";
MySqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
AccountId = reader.GetInt32(0);
string passhash = !reader.IsDBNull(1) ? reader.GetString(1) : null;
string salt = !reader.IsDBNull(2) ? reader.GetString(2) : null;
m_pin = !reader.IsDBNull(3) ? reader.GetString(3) : null;
Gender = !reader.IsDBNull(4) ? reader.GetByte(4) : WvsCommon.Gender.UNDEFINED;
m_birthday = !reader.IsDBNull(5) ? reader.GetInt32(5) : 0;
if (!HashFunctions.HashEquals(pwd, HashAlgorithms.SHA512, passhash + salt))
{
if (passhash == pwd || salt == null && HashFunctions.HashEquals(pwd, HashAlgorithms.SHA1, passhash))
{
salt = HashFunctions.GenerateSalt();
passhash = HashFunctions.GenerateSaltedSha512Hash(pwd, salt);
MySqlCommand update = con.CreateCommand();
update.CommandText = "UPDATE `accounts` SET `password` = '" + passhash + "', `salt` = '" + salt + "' WHERE `id` = " + AccountId;
update.ExecuteNonQuery();
update.Dispose();
}
}
}
reader.Close();
cmd.Dispose();
更新コードを移動することが唯一の可能性である場合、またはそれが最良のものである場合、私はそれでやらなければならないと思いますが、最初に他の可能性についてより多くのアイデアを得てからオプションを選択したいと思います。