KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > continuent > sequoia > controller > locks > DeadlockDetectionThread


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2005 Emic Networks
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Emmanuel Cecchet.
22  * Contributor(s): ______________________.
23  */

24
25 package org.continuent.sequoia.controller.locks;
26
27 import java.sql.SQLException JavaDoc;
28
29 import org.continuent.sequoia.common.log.Trace;
30 import org.continuent.sequoia.controller.backend.DatabaseBackend;
31 import org.continuent.sequoia.controller.loadbalancer.BackendTaskQueueEntry;
32 import org.continuent.sequoia.controller.loadbalancer.BackendTaskQueues;
33 import org.continuent.sequoia.controller.virtualdatabase.VirtualDatabase;
34
35 /**
36  * This class defines a DeadlockDetectionThread that runs periodically to detect
37  * possible deadlocks in the wait for graph of a given database schema.
38  *
39  * @author <a HREF="mailto:emmanuel.cecchet@emicnetworks.com">Emmanuel Cecchet</a>
40  * @version 1.0
41  */

42 public class DeadlockDetectionThread extends Thread JavaDoc
43 {
44   private DatabaseBackend backend;
45   private VirtualDatabase vdb;
46   private Object JavaDoc dbsLock;
47   private long timeout;
48   private boolean killed = false;
49   private BackendTaskQueues queues;
50   private WaitForGraph waitForGraph;
51   protected static Trace logger = Trace
52                                        .getLogger("org.continuent.sequoia.controller.loadbalancer");
53
54   /**
55    * Creates a new <code>DeadlockDetectionThread</code> object
56    *
57    * @param backend the backend we are taking care of
58    * @param vdb virtual database the backend is attached to
59    * @param dbsLock the object on which we can synchronize to prevent database
60    * schema modifications while we are running the deadlock detection
61    * algorithm
62    * @param timeout the time to wait before starting to look for deadlocks
63    */

64   public DeadlockDetectionThread(DatabaseBackend backend, VirtualDatabase vdb,
65       Object JavaDoc dbsLock, long timeout)
66   {
67     super("Deadlock detection thread");
68     this.backend = backend;
69     this.vdb = vdb;
70     this.dbsLock = dbsLock;
71     this.timeout = timeout;
72     this.queues = backend.getTaskQueues();
73     waitForGraph = new WaitForGraph(backend, queues.getStoredProcedureQueue());
74   }
75
76   /**
77    * Terminate this thread
78    */

79   public synchronized void kill()
80   {
81     killed = true;
82     notify();
83   }
84
85   /**
86    * @see java.lang.Thread#run()
87    */

88   public void run()
89   {
90     BackendTaskQueueEntry lastEntry = queues
91         .getFirstConflictingRequestQueueOrStoredProcedureQueueEntry();
92     BackendTaskQueueEntry newEntry;
93     while (!killed)
94     {
95       newEntry = queues
96           .getFirstConflictingRequestQueueOrStoredProcedureQueueEntry();
97       synchronized (this)
98       {
99         if ((newEntry == null) || (newEntry != lastEntry))
100         { // Queue empty or queue has changed
101
lastEntry = newEntry;
102           try
103           {
104             wait(timeout);
105           }
106           catch (InterruptedException JavaDoc ignore)
107           {
108           }
109         }
110         else
111         { // Queue seems stucked, it is not empty and we have
112
// newEntry==lastEntry. Let's look for deadlocks
113
boolean deadlockDetected;
114           long tid = 0;
115           synchronized (dbsLock)
116           {
117             deadlockDetected = waitForGraph.detectDeadlocks();
118             if (deadlockDetected)
119             { // Need to abort the transaction
120
tid = waitForGraph.getVictimTransactionId();
121             }
122             // Prevent infinite loop and let's sleep for a while since there
123
// is no one to kill now
124
lastEntry = null;
125           } // synchronized (dbsLock)
126
if (deadlockDetected)
127           {
128             if (logger.isInfoEnabled())
129               logger.info("Deadlock detected on backend " + backend.getName()
130                   + ", aborting transaction " + tid);
131
132             try
133             {
134               // Abort the transaction
135
vdb.abort(tid, true, true);
136             }
137             catch (SQLException JavaDoc e)
138             {
139               logger.warn("Failed to abort transaction " + tid, e);
140             }
141           }
142         } // else
143
} // synchronized
144
} // while
145
}
146
147 }
148
Popular Tags