पर डेडलॉक मुझे SQL Server 2008 पर SELECT/UPDATE पर डेडलॉक के साथ कोई समस्या हो रही है। मैंने इस धागे से उत्तर पढ़े हैं: SQL Server deadlocks between select/update or multiple selects लेकिन मुझे अभी भी समझ में नहीं आता कि मुझे डेडलॉक क्यों मिलता है।SELECT/UPDATE
मैंने निम्नलिखित टेस्टकेस में स्थिति को फिर से बनाया है।
मैं एक मेज है:
CREATE TABLE [dbo].[SessionTest](
[SessionId] UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL,
[ExpirationTime] DATETIME NOT NULL,
CONSTRAINT [PK_SessionTest] PRIMARY KEY CLUSTERED (
[SessionId] ASC
) WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[SessionTest]
ADD CONSTRAINT [DF_SessionTest_SessionId]
DEFAULT (NEWID()) FOR [SessionId]
GO
मैं इस तालिका से एक रिकॉर्ड का चयन करने के पहले कोशिश कर रहा हूँ और रिकॉर्ड वर्तमान समय के साथ साथ कुछ अंतराल के लिए सेट समाप्ति समय मौजूद रहने पर। यह निम्नलिखित कोड का उपयोग कर पूरा किया है: अगर मैं दो धागे से परीक्षा पद्धति पर अमल करने की कोशिश
protected Guid? GetSessionById(Guid sessionId, SqlConnection connection, SqlTransaction transaction)
{
Logger.LogInfo("Getting session by id");
using (SqlCommand command = new SqlCommand())
{
command.CommandText = "SELECT * FROM SessionTest WHERE SessionId = @SessionId";
command.Connection = connection;
command.Transaction = transaction;
command.Parameters.Add(new SqlParameter("@SessionId", sessionId));
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.Read())
{
Logger.LogInfo("Got it");
return (Guid)reader["SessionId"];
}
else
{
return null;
}
}
}
}
protected int UpdateSession(Guid sessionId, SqlConnection connection, SqlTransaction transaction)
{
Logger.LogInfo("Updating session");
using (SqlCommand command = new SqlCommand())
{
command.CommandText = "UPDATE SessionTest SET ExpirationTime = @ExpirationTime WHERE SessionId = @SessionId";
command.Connection = connection;
command.Transaction = transaction;
command.Parameters.Add(new SqlParameter("@ExpirationTime", DateTime.Now.AddMinutes(20)));
command.Parameters.Add(new SqlParameter("@SessionId", sessionId));
int result = command.ExecuteNonQuery();
Logger.LogInfo("Updated");
return result;
}
}
public void UpdateSessionTest(Guid sessionId)
{
using (SqlConnection connection = GetConnection())
{
using (SqlTransaction transaction = connection.BeginTransaction(IsolationLevel.Serializable))
{
if (GetSessionById(sessionId, connection, transaction) != null)
{
Thread.Sleep(1000);
UpdateSession(sessionId, connection, transaction);
}
transaction.Commit();
}
}
}
तो और वे एक ही रिकॉर्ड को अपडेट करने मैं उत्पादन निम्नलिखित पाने की कोशिश:
[4] : Creating/updating session
[3] : Creating/updating session
[3] : Getting session by id
[3] : Got it
[4] : Getting session by id
[4] : Got it
[3] : Updating session
[4] : Updating session
[3] : Updated
[4] : Exception: Transaction (Process ID 59) was deadlocked
on lock resources with another process and has been
chosen as the deadlock victim. Rerun the transaction.
मैं कैसे नहीं समझ सकता यह Serializable अलगाव स्तर का उपयोग कर हो सकता है। मुझे लगता है कि पहले चयन करें पंक्ति/तालिका को लॉक करना चाहिए और किसी अन्य ताले को प्राप्त करने के लिए किसी अन्य को चुनने नहीं देगा। उदाहरण कमांड ऑब्जेक्ट्स का उपयोग करके लिखा गया है लेकिन यह केवल परीक्षण उद्देश्यों के लिए है। मूल रूप से, मैं linq का उपयोग कर रहा हूँ लेकिन मैं सरलीकृत उदाहरण दिखाना चाहता था। एसक्यूएल सर्वर प्रोफाइलर से पता चलता है कि डेडलॉक कुंजी लॉक है। मैं कुछ मिनटों में प्रश्न अपडेट करूँगा और एसक्यूएल सर्वर प्रोफाइलर से ग्राफ पोस्ट करूंगा। किसी भी सहायता की सराहना की जाएगी। मैं समझता हूं कि इस समस्या का समाधान कोड में महत्वपूर्ण खंड बना रहा है लेकिन मैं समझने की कोशिश कर रहा हूं कि सीरियलज़ेबल अलगाव स्तर चाल क्यों नहीं करता है। deadlock http://img7.imageshack.us/img7/9970/deadlock.gif
अग्रिम धन्यवाद:
और यहाँ गतिरोध ग्राफ है।
+1! –