我創建了一個方法,而回的是:如何使用SqlClient在ADO.NET/C#4.0中解開SQL Server 2008表?
- 鎖定表
- 讀值從它
- 寫道更新值回
- 解鎖表
代碼就職於甲骨文。現在我無法得到它的SQL Server 2008的方法如下,並用文本執行的SqlException
我的解鎖命令結果的工作:
「NOLOC」是不是一個公認的表提示選項。如果它的目的是作爲一個 參數表值函數或CHANGETABLE函數, 確保您的數據庫兼容模式設置爲90
代碼:
public static int GetAndSetMaxIdTable(DbProviderFactory factory, DbConnection cnctn, DbTransaction txn, int tableId, string userName, int numberOfIds)
{
bool isLocked = false;
string sql = string.Empty;
string maxIdTableName;
if (tableId == 0)
maxIdTableName = "IdMax";
else
maxIdTableName = "IdMaxTable";
try
{
bool noPrevRow = false;
int realMaxId;
if (factory is OracleClientFactory)
sql = string.Format("lock table {0} in exclusive mode", maxIdTableName);
else if (factory is SqlClientFactory)
sql = string.Format("select * from {0} with (TABLOCKX)", maxIdTableName);
else
throw new Exception(string.Format("Unsupported DbProviderFactory -type: {0}", factory.GetType().ToString()));
using (DbCommand lockCmd = cnctn.CreateCommand())
{
lockCmd.CommandText = sql;
lockCmd.Transaction = txn;
lockCmd.ExecuteNonQuery();
isLocked = true;
}
using (DbCommand getCmd = cnctn.CreateCommand())
{
getCmd.CommandText = CreateSelectCommand(factory, tableId, userName, getCmd, txn);
object o = getCmd.ExecuteScalar();
if (o == null)
{
noPrevRow = true;
realMaxId = 0;
}
else
{
realMaxId = Convert.ToInt32(o);
}
}
using (DbCommand setCmd = cnctn.CreateCommand())
{
if (noPrevRow)
setCmd.CommandText = CreateInsertCommand(factory, tableId, userName, numberOfIds, realMaxId, setCmd, txn);
else
setCmd.CommandText = CreateUpdateCommand(factory, tableId, userName, numberOfIds, realMaxId, setCmd, txn);
setCmd.ExecuteNonQuery();
}
if (factory is OracleClientFactory)
sql = string.Format("lock table {0} in share mode", maxIdTableName);
else if (factory is SqlClientFactory)
sql = string.Format("select * from {0} with (NOLOC)", maxIdTableName);
using (DbCommand lockCmd = cnctn.CreateCommand())
{
lockCmd.CommandText = sql;
lockCmd.Transaction = txn;
lockCmd.ExecuteNonQuery();
isLocked = false;
}
return realMaxId;
}
catch (Exception e)
{
...
}
}
那麼什麼這裏出錯了?這個錯誤來自哪裏?服務器或客戶端?我複製了C代碼中的聲明,它應該在那裏工作。不幸的是,我無法調試並檢查它是否適用於我。
編輯:只是想鎖定和解鎖(不讀或更新),在同樣的異常結果。
感謝& BR -Matti
那麼它的一件事NOLOCK。你真的想要鎖定整個表中的其他所有可能的過程嗎?通常做這種事情的方法是在事務中,它可以在Oracle和SQL Server上工作。如果你想要這條路線,你不需要Oracle或SQL Server Specific Sql,並且使用IDbConnection,IDbCommand等,你可以擺脫大部分如果Oracle的東西,並得到接近於提供者不可知論 –
謝謝4你回答託尼。是的,每個試圖訪問表的客戶端都必須被鎖定。我想首先得到這項工作,但我也接受更復雜的方法。如果你不知道爲什麼我會得到這個例外,你可以發表一個例子來說明如何用交易來做到這一點。事實上,我已經在這裏使用了一個交易,但顯然你提出的方法是別的。 –
如果您始終鎖定整個表格,那將會是一個緩慢的應用程序。 –