Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

143 lines
4.5 KiB
C#

//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Data;
using System.Runtime.InteropServices;
namespace IBM.Data.DB2
{
public sealed class DB2Transaction : MarshalByRefObject, IDbTransaction
{
private enum TransactionState
{
Open,
Committed,
Rolledback,
}
IsolationLevel isolationLevel;
DB2Connection db2Conn;
TransactionState state;
internal DB2Transaction(DB2Connection con, IsolationLevel isoL)
{
long db2IsoL;
db2Conn = con;
short sqlRet;
isolationLevel = isoL;
switch (isoL)
{
default:
case System.Data.IsolationLevel.Chaos: //No DB2equivalent, default to SQL_TXN_READ_COMMITTED
case System.Data.IsolationLevel.ReadCommitted: //SQL_TXN_READ_COMMITTED
db2IsoL = DB2Constants.SQL_TXN_READ_COMMITTED;
break;
case System.Data.IsolationLevel.ReadUncommitted: //SQL_TXN_READ_UNCOMMITTED
db2IsoL = DB2Constants.SQL_TXN_READ_UNCOMMITTED;
break;
case System.Data.IsolationLevel.RepeatableRead: //SQL_TXN_REPEATABLE_READ
db2IsoL = DB2Constants.SQL_TXN_REPEATABLE_READ;
break;
case System.Data.IsolationLevel.Serializable: //SQL_TXN_SERIALIZABLE_READ
db2IsoL = DB2Constants.SQL_TXN_SERIALIZABLE_READ;
break;
}
if(db2Conn.openConnection.autoCommit)
{
sqlRet = DB2CLIWrapper.SQLSetConnectAttr(db2Conn.DBHandle, DB2Constants.SQL_ATTR_AUTOCOMMIT, new IntPtr(DB2Constants.SQL_AUTOCOMMIT_OFF), 0);
DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, "Error setting AUTOCOMMIT OFF in transaction CTOR.", db2Conn);
db2Conn.openConnection.autoCommit = false;
}
sqlRet = DB2CLIWrapper.SQLSetConnectAttr(db2Conn.DBHandle, DB2Constants.SQL_ATTR_TXN_ISOLATION, new IntPtr(db2IsoL), 0);
DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, "Error setting isolation level.", db2Conn);
state = TransactionState.Open;
}
/// <summary>
/// DB2Connection associated with this transaction
/// </summary>
public IDbConnection Connection
{
get
{
return db2Conn;
}
}
/// <summary>
/// IsolationLevel property
/// </summary>
///
public IsolationLevel IsolationLevel
{
get
{
CheckStateOpen();
return isolationLevel;
}
}
internal void CheckStateOpen()
{
if(state == TransactionState.Committed)
throw new InvalidOperationException("Transaction was already committed. It is no longer usable.");
if(state == TransactionState.Rolledback)
throw new InvalidOperationException("Transaction was already rolled back. It is no longer usable.");
}
public void Commit()
{
CheckStateOpen();
DB2CLIWrapper.SQLEndTran(DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, DB2Constants.SQL_COMMIT);
this.state = TransactionState.Committed;
this.db2Conn.openConnection.transactionOpen = false;
this.db2Conn.WeakRefTransaction = null;
this.db2Conn = null;
}
public void Rollback()
{
CheckStateOpen();
DB2CLIWrapper.SQLEndTran(DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, DB2Constants.SQL_ROLLBACK);
this.db2Conn.openConnection.transactionOpen = false;
this.state = TransactionState.Rolledback;
this.db2Conn.WeakRefTransaction = null;
this.db2Conn = null;
}
/// <summary>
/// Dispose method.
/// </summary>
public void Dispose()
{
if (state != TransactionState.Open)
return;
Rollback();
}
}
}