// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as published by
// the Free Software Foundation
//
// There are special exceptions to the terms and conditions of the GPL
// as it is applied to this software. View the full text of the
// exception in file EXCEPTIONS in the directory of this software
// distribution.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
using System.Data;
using System.IO;
using NUnit.Framework;
using System.Data.Common;
using System.Reflection;
namespace MySql.Data.MySqlClient.Tests
{
[TestFixture]
public class SimpleTransactions : BaseTest
{
public override void Setup()
{
base.Setup();
createTable("CREATE TABLE Test (key2 VARCHAR(1), name VARCHAR(100), name2 VARCHAR(100))", "INNODB");
}
[Test]
public void TestReader()
{
execSQL("INSERT INTO Test VALUES('P', 'Test1', 'Test2')");
MySqlTransaction txn = conn.BeginTransaction();
MySqlConnection c = txn.Connection;
Assert.AreEqual( conn, c );
MySqlCommand cmd = new MySqlCommand("SELECT name, name2 FROM Test WHERE key2='P'",
conn, txn);
MySqlTransaction t2 = cmd.Transaction;
Assert.AreEqual( txn, t2 );
MySqlDataReader reader = null;
try
{
reader = cmd.ExecuteReader();
reader.Close();
txn.Commit();
}
catch (Exception ex)
{
Assert.Fail( ex.Message );
txn.Rollback();
}
finally
{
if (reader != null) reader.Close();
}
}
///
/// Bug #22400 Nested transactions
///
[Test]
public void NestedTransactions()
{
MySqlTransaction t1 = conn.BeginTransaction();
try
{
MySqlTransaction t2 = conn.BeginTransaction();
Assert.Fail("Exception should have been thrown");
t2.Rollback();
}
catch (InvalidOperationException)
{
}
finally
{
t1.Rollback();
}
}
[Test]
public void BeginTransactionOnPreviouslyOpenConnection()
{
string connStr = GetConnectionString(true);
MySqlConnection c = new MySqlConnection(connStr);
c.Open();
c.Close();
try
{
c.BeginTransaction();
}
catch (Exception ex)
{
Assert.AreEqual("The connection is not open.", ex.Message);
}
}
///
/// Bug #37991 Connection fails when trying to close after a commit while network to db is bad
/// This test is not a perfect test of this bug as the kill connection is not quite the
/// same as unplugging the network but it's the best I've figured out so far
///
[Test]
public void CommitAfterConnectionDead()
{
execSQL("DROP TABLE IF EXISTS Test");
execSQL("CREATE TABLE Test(id INT, name VARCHAR(20))");
string connStr = GetConnectionString(true) + ";pooling=false";
using (MySqlConnection c = new MySqlConnection(connStr))
{
c.Open();
MySqlTransaction trans = c.BeginTransaction();
using (MySqlCommand cmd = new MySqlCommand("INSERT INTO Test VALUES (1, 'boo')", c))
{
cmd.ExecuteNonQuery();
}
KillConnection(c);
try
{
trans.Commit();
Assert.Fail("Should have thrown an exception");
}
catch (Exception)
{
}
Assert.AreEqual(ConnectionState.Closed, c.State);
c.Close(); // this should work even though we are closed
}
}
///
/// Bug #39817 Transaction Dispose does not roll back
///
[Test]
public void DisposingCallsRollback()
{
MySqlCommand cmd = new MySqlCommand("INSERT INTO Test VALUES ('a', 'b', 'c')", conn);
MySqlTransaction txn = conn.BeginTransaction();
using (txn)
{
cmd.ExecuteNonQuery();
}
// the txn should be closed now as a rollback should have happened.
Type t = txn.GetType();
FieldInfo fi = t.GetField("open", BindingFlags.Instance | BindingFlags.NonPublic);
bool isOpen = (bool)fi.GetValue(txn);
Assert.IsFalse(isOpen);
}
}
}