<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>UGamela Blog &#187; MySQL Prozedur</title>
	<atom:link href="http://ugamela-blog.pheelgood.net/tag/mysql-prozedur/feed/" rel="self" type="application/rss+xml" />
	<link>http://ugamela-blog.pheelgood.net</link>
	<description>Entwicklung eines Browsergames</description>
	<lastBuildDate>Mon, 12 Dec 2011 18:28:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Race Conditions, ein BG Problem (Flottenverdoppelung)</title>
		<link>http://ugamela-blog.pheelgood.net/2008/09/15/race-conditions-ein-bg-problem-flottenverdoppelung/</link>
		<comments>http://ugamela-blog.pheelgood.net/2008/09/15/race-conditions-ein-bg-problem-flottenverdoppelung/#comments</comments>
		<pubDate>Mon, 15 Sep 2008 16:43:37 +0000</pubDate>
		<dc:creator>Phoscur</dc:creator>
				<category><![CDATA[Entwicklung]]></category>
		<category><![CDATA[Flottenverdoppelung]]></category>
		<category><![CDATA[MySQL Prozedur]]></category>
		<category><![CDATA[Phlame]]></category>
		<category><![CDATA[Race Condition]]></category>

		<guid isPermaLink="false">http://ugamela-blog.pheelgood.net/?p=65</guid>
		<description><![CDATA[Ich werde nun nicht nochmal selbst Race Conditions erklären, wenn das schon sehr gut auf Wikipedia beschrieben ist. Link Bei einem PHP Apache Server agieren ständig mehrere Threads, Scripte oder System (wie auch immer man sie nennen will) gleichzeitig. Jedes Mal wenn ein User einen Script aufruft (quasi immer wenn er irgendwo draufdrückt), wird ein [...]]]></description>
			<content:encoded><![CDATA[<p>Ich werde nun nicht nochmal selbst Race Conditions erklären, wenn das schon sehr gut auf Wikipedia beschrieben ist. <a title="Wikipedia: Race Condition" href="http://de.wikipedia.org/wiki/Race_Condition">Link</a></p>
<p>Bei einem PHP Apache Server agieren ständig mehrere Threads, Scripte oder System (wie auch immer man sie nennen will) gleichzeitig. Jedes Mal wenn ein User einen Script aufruft (quasi immer wenn er irgendwo draufdrückt), wird ein neuer Thread für ihn gebildet, dieser läuft parallel zu den anderen.</p>
<p>Ein BG (Browsergame) wie UGamela hat &#8211; wie Viele gar nicht wissen &#8211; eine komplexe Spiellogik im Inneren, welche bei bisherigen Versionen nur hingemurkst wurde. Beispiel siehe <a title="Link zum Thema" href="http://ugamela-blog.pheelgood.net/tag/fusionskraftwerkbug/">Fusionskraftwerkbug</a>.</p>
<p>Ein weiteres Problem stellt die insgesamt schlechte Programmierung und somit unnötig und zu lange Berechnungszeit der Scripte dar, je länger der zeitliche Abstand zwischen dem SQL Select Befehl und dem SQL Update Befehl, desto höher die Wahrscheinlichkeit, dass es zu einem Race Condition bedingten Fehler kommt.</p>
<p>Häufigster bekannter Fehler dieser Art ist das Problem der Flottenverdoppelung!</p>
<p>Problemlösung ist in diesem Fall wirklich nicht so einfach, vor allem wenn man nicht noch längere Berechnungszeiten und somit irgendwann Wartezeiten für die User riskieren will.</p>
<p>MySQL stellt dafür einen Befehl bereit, der eine ganze Tabelle sperrt (&#8220;LOCK TABLE `xx`&#8221;) &#8211; anstehende Queries warten. Für die ganze Tabelle!! Dh letztendlich für alle Threads, dabei ist gar nicht klar, ob sich die Queries überhaupt überschneiden. Bei größeren Userzahlen gleichzeitig wird das dann wirklich spaßig, wenn die Wartezeiten immer länger werden.</p>
<p>Interessanter wäre es doch die einzelnen Einträge zu Sperren. Doch dies ist mit einigem Aufwand verbunden, weil ich aus Performancegründen benötigte Daten in einem Rutsch laden will (zB die Planeten des Spielers gleichzeitig). Dennoch soll es tief im Grundgerüst verankert werden, sodass letztlich der Modder keine Ahnung davon haben muss. Er schreibt höchstens sein spezielles &#8220;WHERE&#8221; im SQL Select Befehl.</p>
<p>Hier ein kleiner Einblick: <span id="more-65"></span></p>
<blockquote><p>PREPARE wtnu FROM &#8216;SELECT `used` INTO @used FROM `?pre&#8221;.$table.&#8221;` WHERE &#8220;.$where.&#8221; &#8216;<br />
oder PREPARE wtnu FROM &#8216;SELECT SUM(`used`) AS @used FROM `?pre&#8221;.$table.&#8221;` WHERE &#8220;.$where.&#8221; &#8216;</p>
<p>CREATE PROCEDURE wtnu ()<br />
COMMENT &#8216;wait till not used&#8217;<br />
BEGIN<br />
wloop: LOOP<br />
EXECUTE wtnu;<br />
IF @used &lt;= 0 THEN<br />
LEAVE wloop;<br />
END IF;<br />
SLEEP(0.3);<br />
ITERATE wloop;<br />
END LOOP wloop;<br />
END|</p></blockquote>
<p>1. Query vorbereiten (kommt auf ein oder mehrere Einträge an)<br />
2. Die gezeigt Prozedur aufrufen:<br />
2.1. Vorbereitetes Query aufrufen<br />
2.2. Testen, ob der/die Eintrag/Einträge in Benutzung &#8220;used&#8221; sind.<br />
- wenn ja, warten.. die Schleife beginnt bei 2.1 von neuem.<br />
- wenn nein verlasse die Schleife</p>
<p>Ich muss noch etwas daran feilen, ich weiß noch nicht wie ich das Session Caching miteinbinde und ob die Abfrage für mehrere &#8220;used&#8221; schon das Wahre ist (ein SUM [Summe] Befehl überprüft ob die Einträge zusammen nicht mehr als 0 sind, &#8220;used&#8221; kann 0 oder 1 sein).</p>
]]></content:encoded>
			<wfw:commentRss>http://ugamela-blog.pheelgood.net/2008/09/15/race-conditions-ein-bg-problem-flottenverdoppelung/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

