Another attempt at deadlock elimination.
1.1 --- a/mdr/extras/jdbcstorage/src/org/netbeans/mdr/persistence/jdbcimpl/JdbcPrimaryIndex.java Wed Jan 19 01:00:18 2005 +0000
1.2 +++ b/mdr/extras/jdbcstorage/src/org/netbeans/mdr/persistence/jdbcimpl/JdbcPrimaryIndex.java Wed Jan 19 22:40:47 2005 +0000
1.3 @@ -28,6 +28,8 @@
1.4 class JdbcPrimaryIndex
1.5 extends JdbcSinglevaluedIndex implements MDRCache.OverflowHandler
1.6 {
1.7 + // NOTE: around cache access sequences, we synchronize on
1.8 + // the parent storage, not on "this", to prevent deadlock
1.9 private final MDRCache cache;
1.10
1.11 // NOTE: most of this class was ripped from BtreeDatabase
1.12 @@ -160,7 +162,7 @@
1.13 public boolean put(
1.14 Object key,Object value) throws StorageException
1.15 {
1.16 - synchronized(cache) {
1.17 + synchronized(storage) {
1.18 MOFID mKey = makeMOFID(key);
1.19 if (!exists(mKey)) {
1.20 addToCache(mKey,value);
1.21 @@ -176,7 +178,7 @@
1.22 public void replace(Object key, Object value)
1.23 throws StorageException, StorageBadRequestException
1.24 {
1.25 - synchronized(cache) {
1.26 + synchronized(storage) {
1.27 MOFID mKey = makeMOFID(key);
1.28
1.29 if (!exists(mKey)) {
1.30 @@ -209,7 +211,7 @@
1.31 // override JdbcSinglevaluedIndex
1.32 public Object getIfExists(Object key) throws StorageException
1.33 {
1.34 - synchronized(cache) {
1.35 + synchronized(storage) {
1.36 MOFID mKey = makeMOFID(key);
1.37 Object retval;
1.38 retval = cache.get(mKey);
1.39 @@ -254,7 +256,7 @@
1.40 public void add(
1.41 Object key, Object value) throws StorageException
1.42 {
1.43 - synchronized(cache) {
1.44 + synchronized(storage) {
1.45 MOFID mKey = makeMOFID(key);
1.46 if (exists(mKey)) {
1.47 throw new StorageBadRequestException(
1.48 @@ -268,7 +270,7 @@
1.49 // override JdbcIndex
1.50 public boolean remove(Object key) throws StorageException
1.51 {
1.52 - synchronized(cache) {
1.53 + synchronized(storage) {
1.54 MOFID mKey = makeMOFID(key);
1.55 if (!exists(mKey)) {
1.56 return false;
2.1 --- a/mdr/extras/jdbcstorage/src/org/netbeans/mdr/persistence/jdbcimpl/JdbcStorage.java Wed Jan 19 01:00:18 2005 +0000
2.2 +++ b/mdr/extras/jdbcstorage/src/org/netbeans/mdr/persistence/jdbcimpl/JdbcStorage.java Wed Jan 19 22:40:47 2005 +0000
2.3 @@ -63,8 +63,6 @@
2.4
2.5 private final Map entryTypeToDataTypeMap;
2.6
2.7 - private final Object connectionMutex;
2.8 -
2.9 private Statement jdbcStmt;
2.10
2.11 private ResultSet jdbcResultSet;
2.12 @@ -125,10 +123,6 @@
2.13 JdbcStorageFactory.STORAGE_QUERY_DUPLICATES,
2.14 false);
2.15
2.16 - // we use a private object for synchronization on the JDBC connection
2.17 - // because external code synchronizes on "this" storage object
2.18 - connectionMutex = new Object();
2.19 -
2.20 boolean success = false;
2.21
2.22 try {
2.23 @@ -917,88 +911,82 @@
2.24 }
2.25 }
2.26
2.27 - ListIterator getResultSetIterator(
2.28 + synchronized ListIterator getResultSetIterator(
2.29 LazyPreparedStatement lps,Object [] args,EntryType entryType)
2.30 throws StorageException
2.31 {
2.32 - synchronized(connectionMutex) {
2.33 + try {
2.34 + PreparedStatement ps = prepareStatement(lps);
2.35 + bindArgs(ps,args);
2.36 + jdbcResultSet = ps.executeQuery();
2.37 + // TODO: assert exactly one column
2.38 + List list = new ArrayList();
2.39 try {
2.40 - PreparedStatement ps = prepareStatement(lps);
2.41 - bindArgs(ps,args);
2.42 - jdbcResultSet = ps.executeQuery();
2.43 - // TODO: assert exactly one column
2.44 - List list = new ArrayList();
2.45 - try {
2.46 - while (jdbcResultSet.next()) {
2.47 - Object obj = getResultObj(entryType);
2.48 - list.add(obj);
2.49 - }
2.50 - } finally {
2.51 - closeResultSet();
2.52 + while (jdbcResultSet.next()) {
2.53 + Object obj = getResultObj(entryType);
2.54 + list.add(obj);
2.55 }
2.56 - if (entryType == EntryType.STREAMABLE) {
2.57 - // Postprocess the returned byte arrays, converting them
2.58 - // into real objects. Note that we do this outside of the
2.59 - // main fetch loop to avoid nasty reentrancy issues.
2.60 - ListIterator listIter = list.listIterator();
2.61 - while (listIter.hasNext()) {
2.62 - byte [] bytes = (byte []) listIter.next();
2.63 - listIter.set(readByteArray(bytes));
2.64 - }
2.65 + } finally {
2.66 + closeResultSet();
2.67 + }
2.68 + if (entryType == EntryType.STREAMABLE) {
2.69 + // Postprocess the returned byte arrays, converting them
2.70 + // into real objects. Note that we do this outside of the
2.71 + // main fetch loop to avoid nasty reentrancy issues.
2.72 + ListIterator listIter = list.listIterator();
2.73 + while (listIter.hasNext()) {
2.74 + byte [] bytes = (byte []) listIter.next();
2.75 + listIter.set(readByteArray(bytes));
2.76 }
2.77 - return list.listIterator();
2.78 - } catch (SQLException ex) {
2.79 - throw newJdbcException(ex);
2.80 }
2.81 + return list.listIterator();
2.82 + } catch (SQLException ex) {
2.83 + throw newJdbcException(ex);
2.84 }
2.85 }
2.86
2.87 - int getResultSetCount(
2.88 + synchronized int getResultSetCount(
2.89 LazyPreparedStatement lps,Object [] args)
2.90 throws StorageException
2.91 {
2.92 - synchronized(connectionMutex) {
2.93 + try {
2.94 + PreparedStatement ps = prepareStatement(lps);
2.95 + bindArgs(ps,args);
2.96 + jdbcResultSet = ps.executeQuery();
2.97 try {
2.98 - PreparedStatement ps = prepareStatement(lps);
2.99 - bindArgs(ps,args);
2.100 - jdbcResultSet = ps.executeQuery();
2.101 - try {
2.102 - int n = 0;
2.103 - while (jdbcResultSet.next()) {
2.104 - ++n;
2.105 - }
2.106 - return n;
2.107 - } finally {
2.108 - closeResultSet();
2.109 + int n = 0;
2.110 + while (jdbcResultSet.next()) {
2.111 + ++n;
2.112 }
2.113 - } catch (SQLException ex) {
2.114 - throw newJdbcException(ex);
2.115 + return n;
2.116 + } finally {
2.117 + closeResultSet();
2.118 }
2.119 + } catch (SQLException ex) {
2.120 + throw newJdbcException(ex);
2.121 }
2.122 }
2.123
2.124 - int getSingletonInt(
2.125 + synchronized int getSingletonInt(
2.126 LazyPreparedStatement lps,Object [] args)
2.127 throws StorageException
2.128 {
2.129 - synchronized(connectionMutex) {
2.130 + try {
2.131 + PreparedStatement ps = prepareStatement(lps);
2.132 + bindArgs(ps,args);
2.133 + jdbcResultSet = ps.executeQuery();
2.134 try {
2.135 - PreparedStatement ps = prepareStatement(lps);
2.136 - bindArgs(ps,args);
2.137 - jdbcResultSet = ps.executeQuery();
2.138 - try {
2.139 - // TODO: assert exactly one column
2.140 - if (!jdbcResultSet.next()) {
2.141 - return -1;
2.142 - }
2.143 - int n = jdbcResultSet.getInt(1);
2.144 - return n;
2.145 - } finally {
2.146 - closeResultSet();
2.147 + // TODO: assert exactly one column
2.148 + if (!jdbcResultSet.next()) {
2.149 + return -1;
2.150 }
2.151 - } catch (SQLException ex) {
2.152 - throw newJdbcException(ex);
2.153 + int n = jdbcResultSet.getInt(1);
2.154 + return n;
2.155 + } finally {
2.156 + closeResultSet();
2.157 }
2.158 + } catch (SQLException ex) {
2.159 + throw newJdbcException(ex);
2.160 }
2.161 }
2.162
2.163 @@ -1045,17 +1033,15 @@
2.164 return data;
2.165 }
2.166
2.167 - int executeUpdate(LazyPreparedStatement lps,Object [] args)
2.168 + synchronized int executeUpdate(LazyPreparedStatement lps,Object [] args)
2.169 throws StorageException
2.170 {
2.171 - synchronized(connectionMutex) {
2.172 - try {
2.173 - PreparedStatement ps = prepareStatement(lps);
2.174 - bindArgs(ps,args);
2.175 - return ps.executeUpdate();
2.176 - } catch (SQLException ex) {
2.177 - throw newJdbcException(ex);
2.178 - }
2.179 + try {
2.180 + PreparedStatement ps = prepareStatement(lps);
2.181 + bindArgs(ps,args);
2.182 + return ps.executeUpdate();
2.183 + } catch (SQLException ex) {
2.184 + throw newJdbcException(ex);
2.185 }
2.186 }
2.187 }