防止在Asp.net中使用ado.net并发执行SQL Server存储过程

时间:2017-01-10 23:21:18

标签: c# sql-server concurrency ado.net transaction-isolation

我想阻止两个用户同时执行相同的存储过程。如果两个asp.net请求进入执行该存储过程,那么这些请求应该一个接一个地以串行方式执行。

SQL Server数据库和执行由ado.net处理。

以下任何一种方法都有助于实现这一目标吗?什么是最合适的方法?还有其他方法可以实现同样的目标吗?

  1. 通过将隔离级别设置为Serializable

  2. ,使用ado.net事务执行存储过程
  3. 在存储过程中使用package org.geotools.tutorial.quickstart; import java.io.*; import java.util.List; import java.util.Arrays; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.MultiLineString; import com.vividsolutions.jts.index.SpatialIndex; import com.vividsolutions.jts.index.strtree.STRtree; import com.vividsolutions.jts.linearref.LinearLocation; import com.vividsolutions.jts.linearref.LocationIndexedLine; import org.geotools.data.FeatureSource; import org.geotools.data.FileDataStore; import org.geotools.data.FileDataStoreFinder; import org.geotools.feature.FeatureCollection; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.swing.data.JFileDataStoreChooser; import org.geotools.util.NullProgressListener; import org.opengis.feature.Feature; import org.opengis.feature.FeatureVisitor; import org.opengis.feature.simple.SimpleFeature; import com.opencsv.*; public class SnapToLine { public static void main(String[] args) throws Exception { /* * Open a shapefile. You should choose one with line features * (LineString or MultiLineString geometry) * */ File file = JFileDataStoreChooser.showOpenFile("shp", null); if (file == null) { return; } FileDataStore store = FileDataStoreFinder.getDataStore(file); FeatureSource source = store.getFeatureSource(); // Check that we have line features Class<?> geomBinding = source.getSchema().getGeometryDescriptor().getType().getBinding(); boolean isLine = geomBinding != null && (LineString.class.isAssignableFrom(geomBinding) || MultiLineString.class.isAssignableFrom(geomBinding)); if (!isLine) { System.out.println("This example needs a shapefile with line features"); return; } final SpatialIndex index = new STRtree(); FeatureCollection features = source.getFeatures(); //FeatureCollection featurecollection = source.getFeatures(Query.FIDS); System.out.println("Slurping in features ..."); features.accepts(new FeatureVisitor() { @Override public void visit(Feature feature) { SimpleFeature simpleFeature = (SimpleFeature) feature; Geometry geom = (MultiLineString) simpleFeature.getDefaultGeometry(); // Just in case: check for null or empty geometry if (geom != null) { Envelope env = geom.getEnvelopeInternal(); if (!env.isNull()) { index.insert(env, new LocationIndexedLine(geom)); } } } }, new NullProgressListener()); /* /* * We defined the maximum distance that a line can be from a point * to be a candidate for snapping */ ReferencedEnvelope bounds = features.getBounds(); final double MAX_SEARCH_DISTANCE = bounds.getSpan(0) / 1000.0; int pointsProcessed = 0; int pointsSnapped = 0; long elapsedTime = 0; long startTime = System.currentTimeMillis(); double longiOut; double latiOut; int moved; String lineID = "NA"; //Open up the CSVReader. Reading in line by line to avoid memory failure. CSVReader csvReader = new CSVReader(new FileReader(new File("fakedata.csv"))); String[] rowIn; //open up the CSVwriter String outcsv = "fakedataOUT.csv"; CSVWriter writer = new CSVWriter(new FileWriter(outcsv)); while ((rowIn = csvReader.readNext()) != null) { // Get point and create search envelope pointsProcessed++; double longi = Double.parseDouble(rowIn[0]); double lati = Double.parseDouble(rowIn[1]); Coordinate pt = new Coordinate(longi, lati); Envelope search = new Envelope(pt); search.expandBy(MAX_SEARCH_DISTANCE); /* * Query the spatial index for objects within the search envelope. * Note that this just compares the point envelope to the line envelopes * so it is possible that the point is actually more distant than * MAX_SEARCH_DISTANCE from a line. */ List<LocationIndexedLine> lines = index.query(search); // Initialize the minimum distance found to our maximum acceptable // distance plus a little bit double minDist = MAX_SEARCH_DISTANCE + 1.0e-6; Coordinate minDistPoint = null; for (LocationIndexedLine line : lines) { LinearLocation here = line.project(pt); Coordinate point = line.extractPoint(here); double dist = point.distance(pt); if (dist < minDist) { minDist = dist; minDistPoint = point; lineID = line.toString(); } } if (minDistPoint == null) { // No line close enough to snap the point to System.out.println(pt + "- X"); longiOut = longi; latiOut = lati; moved = 0; lineID = "NA"; } else { System.out.printf("%s - snapped by moving %.4f\n", pt.toString(), minDist); longiOut = minDistPoint.x; latiOut = minDistPoint.y; moved = 1; pointsSnapped++; } //write a new row String [] rowOut = {Double.toString(longiOut), Double.toString(latiOut), Integer.toString(moved), lineID}; writer.writeNext(rowOut); } System.out.printf("Processed %d points (%.2f points per second). \n" + "Snapped %d points.\n\n", pointsProcessed, 1000.0 * pointsProcessed / elapsedTime, pointsSnapped); writer.close(); } } 并在最后发布

2 个答案:

答案 0 :(得分:2)

我建议在架构的中间层,ASP.NET和数据库之间使用排队系统。这样就按顺序请求接收和处理。然后,您可以将系统配置为一次只处理一个请求,

答案 1 :(得分:2)

  

通过设置执行带有ado.net事务的存储过程   隔离级别为Serializable

是的,您可以在您的ado.net事务中使用Serializable隔离级别。它是最高的隔离级别,它依赖于悲观并发控制&amp;通过假设两个事务可能尝试更新相同的数据并使用来确保它们不会保证一致性。 一个事务必须等待另一个事务完成,并且它们可能会死锁。

  

在存储过程中使用sp_getapplock并在最后发布

是的,您可以使用SQL Server应用程序锁sp_getapplock。您必须使用sp_releaseapplock

释放锁定

另一种选择是使用Global Temporary Tables