143 lines
4.5 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|