2010-07-25 Carlos Alberto Cortez <calberto.cortez@gmail.com>
[mono.git] / mcs / class / IBM.Data.DB2 / IBM.Data.DB2 / DB2Transaction.cs
1
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining
4 // a copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to
8 // permit persons to whom the Software is furnished to do so, subject to
9 // the following conditions:
10 // 
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
13 // 
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 using System;\r
23 using System.Data;\r
24 using System.Runtime.InteropServices;\r
25 \r
26 namespace IBM.Data.DB2\r
27 {\r
28         public sealed class DB2Transaction : MarshalByRefObject, IDbTransaction\r
29         {\r
30                 private enum TransactionState\r
31                 {\r
32                         Open,\r
33                         Committed,\r
34                         Rolledback,\r
35                 }\r
36                 IsolationLevel isolationLevel;\r
37                 DB2Connection db2Conn;\r
38                 TransactionState state;\r
39                 \r
40 \r
41 \r
42                 internal DB2Transaction(DB2Connection con, IsolationLevel isoL)\r
43                 {\r
44                         long db2IsoL;\r
45                         db2Conn = con;\r
46                         short sqlRet;\r
47 \r
48                         isolationLevel = isoL;\r
49 \r
50                         switch (isoL) \r
51                         {\r
52                                 default:\r
53                                 case System.Data.IsolationLevel.Chaos:                          //No DB2equivalent, default to SQL_TXN_READ_COMMITTED\r
54                                 case System.Data.IsolationLevel.ReadCommitted:          //SQL_TXN_READ_COMMITTED\r
55                                         db2IsoL = DB2Constants.SQL_TXN_READ_COMMITTED;\r
56                                         break;\r
57                                 case System.Data.IsolationLevel.ReadUncommitted:        //SQL_TXN_READ_UNCOMMITTED\r
58                                         db2IsoL = DB2Constants.SQL_TXN_READ_UNCOMMITTED;\r
59                                         break;\r
60                                 case System.Data.IsolationLevel.RepeatableRead:         //SQL_TXN_REPEATABLE_READ\r
61                                         db2IsoL = DB2Constants.SQL_TXN_REPEATABLE_READ;\r
62                                         break;\r
63                                 case System.Data.IsolationLevel.Serializable:           //SQL_TXN_SERIALIZABLE_READ\r
64                                         db2IsoL = DB2Constants.SQL_TXN_SERIALIZABLE_READ;\r
65                                         break;\r
66                         }\r
67 \r
68                         if(db2Conn.openConnection.autoCommit)\r
69                         {\r
70                                 sqlRet = DB2CLIWrapper.SQLSetConnectAttr(db2Conn.DBHandle, DB2Constants.SQL_ATTR_AUTOCOMMIT, new IntPtr(DB2Constants.SQL_AUTOCOMMIT_OFF), 0);\r
71                                 DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, "Error setting AUTOCOMMIT OFF in transaction CTOR.", db2Conn);\r
72                                 db2Conn.openConnection.autoCommit = false;\r
73                         }\r
74                         sqlRet = DB2CLIWrapper.SQLSetConnectAttr(db2Conn.DBHandle, DB2Constants.SQL_ATTR_TXN_ISOLATION, new IntPtr(db2IsoL), 0);\r
75                         DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, "Error setting isolation level.", db2Conn);\r
76 \r
77                         state = TransactionState.Open;\r
78                 }\r
79 \r
80                 /// <summary>\r
81                 /// DB2Connection associated with this transaction\r
82                 /// </summary>\r
83                 public IDbConnection Connection\r
84                 {\r
85                         get\r
86                         {\r
87                                 return db2Conn;\r
88                         }\r
89                 }\r
90                 /// <summary>\r
91                 /// IsolationLevel property\r
92                 /// </summary>\r
93                 /// \r
94                 public IsolationLevel IsolationLevel\r
95                 {\r
96                         get \r
97                         {\r
98                                 CheckStateOpen();\r
99                                 return isolationLevel;\r
100                         }\r
101                 }\r
102 \r
103                 internal void CheckStateOpen()\r
104                 {\r
105                         if(state == TransactionState.Committed)\r
106                                 throw new InvalidOperationException("Transaction was already committed. It is no longer usable.");\r
107                         if(state == TransactionState.Rolledback)\r
108                                 throw new InvalidOperationException("Transaction was already rolled back. It is no longer usable.");\r
109                 }\r
110 \r
111                 public void Commit() \r
112                 {\r
113                         CheckStateOpen();\r
114                         DB2CLIWrapper.SQLEndTran(DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, DB2Constants.SQL_COMMIT);\r
115                         this.state = TransactionState.Committed;\r
116                         this.db2Conn.openConnection.transactionOpen = false;\r
117                         this.db2Conn.WeakRefTransaction = null;\r
118                         this.db2Conn = null;\r
119                 }\r
120 \r
121                 public void Rollback() \r
122                 {\r
123                         CheckStateOpen();\r
124                         DB2CLIWrapper.SQLEndTran(DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, DB2Constants.SQL_ROLLBACK);\r
125                         this.db2Conn.openConnection.transactionOpen = false;\r
126                         this.state = TransactionState.Rolledback;\r
127                         this.db2Conn.WeakRefTransaction = null;\r
128                         this.db2Conn = null;\r
129                 }\r
130 \r
131                 /// <summary>\r
132                 /// Dispose method.\r
133                 /// </summary>\r
134                 public void Dispose()\r
135                 {\r
136                         if (state != TransactionState.Open) \r
137                                 return;\r
138 \r
139                         Rollback();\r
140                 }\r
141         }\r
142 }\r