For the oci8 extension it is not true that " [...] when using transactions, a transaction block will also carry over to the next script which uses that connection if script execution ends before the transaction block does.". The oci8 extension does a rollback at the end scripts using persistent connections, thus ending the transaction. The rollback also releases locks. However any ALTER SESSION command (e.g. changing the date format) on a persistent connection will be retained over to the next script.
Bölüm 23. Kalıcı Veritabanı Bağlantıları
Kalıcı bağlantılar, betiğiniz sonlandığında kapatılmayan SQL bağlantılarına denir. Kalıcı bir bağlantı istendiğinde, PHP daha önceden tamamen aynı özelliklerde başka bir kalıcı bağlantı açılıp açılmadığına bakar (daha önceden kalan) - ve eğer varsa, onu kullanır. Eğer yoksa, yeni bağlantı kurar. 'Tamamen aynı' bağlantılar, aynı sunucuya, aynı kullanıcı ismi ve (gerekliyse) şifreyle açılmış bağlantılardır.
HTTP sunucularının çalışma mantığına aşina olmayanlar, kalıcı bağlantıları gerçekte olmadıkları şeyler sanabilirler. Özellikle, aynı SQL bağlantısı üzerinde 'kullanıcı oturumları' açmazlar, transaction'ları daha etkili bir şekilde yapmanızı sağlamazlar ve başka pek çok şeyi gerçekleştirmezler. Konu hakkında daha açık olmak gerekirse, kalıcı bağlantılar size kardeşleri kalıcı olmayan bağlantıların sunmadığı hiç bir ek özellik sunmazlar.
Neden?
Bu daha çok HTTP sunucularının çalışma mantığıyla alakalı. Sunucunun PHP'yi kullanarak web sayfaları oluşturmasının üç yöntemi var.
İlk yöntem PHP'yi CGI "sargısı" olarak kullanmak. Bu şekilde çalıştığında, sunucuya gelen her sayfa isteği için ayrı bir PHP yorumlayıcısı yaratılır ve yokedilir (PHP sayfaları için). İşlemler sonunda yokedildikleri için, yarattıkları her kaynak da (SQL sunucusuna bağlantılar gibi) onlarla birlikte yokolur. Bu durumda, kalıcı bağlantılar kurmayı denemekle elinize hiçbirşey geçmez -- basitçe, kalıcı olamazlar.
İkinci, ve en popüler, yöntem PHP'yi çok işlemli (multiprocess) bir sunucuda modül olarak kullanmak, şu an sadece Apache'de olduğu gibi. Çok işlemli bir sunucu genellikle bir ana işlemden (parent) ve onun kontrolündeki gerçekte işlemleri yapan çocuk işlemlerden (children) oluşur. Ne zaman bir alıcıdan istek gelse, istek o anda başka bir isteğe cevap vermeyen bir çocuk işleme devredilir. Bu demektir ki, aynı alıcı ikinci bir istek yolladığında, başka bir çocuk işlem tarafından karşılanabilir. Kalıcı bağlantıların sizin için burada yaptığı iş, her çocuk işlemin sadece ilk seferde SQL sunucusuna bağlanmasıdır. Başka bir sayfanın aynı bağlantıya ihtiyaç duyması durumunda önceden kurulmuş bağlantı kullanılır.
Son yöntem PHP'yi çok iş parçacıklı (multithreaded) sunucularda eklenti olarak kullanmak. Şu anda PHP 4'ün Netscape FastTrack (iPlanet), Microsoft Internet Information Server (IIS), ve O'Reilly Website Pro gibi çok iş parçacıklı sunucularda çalışmasını sağlayan ISAPI, WSAIP, ve NSAPI (Windows'ta) için desteği var. Bu çalışma şekli az önce anlatılan çok işlemli modelle aynı. SAPI desteğinin PHP 3'te olmadığına dikkat edin.
Eğer kalıcı bağlantıların ek özellikleri yoksa, neye yararlar?
Buradaki cevap oldukça basit -- etkinlik. Kalıcı bağlantılar, SQL sunucunuza yeni bağlantı açmak performans açısından hesaplı değilse çok işe yararlar. Performans hesaplılığı pek çok şeye bağlıdır. Örneğin, ne tür bir veritabanı olduğu, HTTP sunucusuyla aynı bilgisayarda olup olmayışı, SQL sunucusunun çalıştığı bilgisayarın işlem yoğunluğu ve benzeri. Sonuç şu ki, yeni bağlantı performansı düşükse, kalıcı bağlantılar işe yarar. Her çocuk işlemin her seferinde yeni bağlantı açması yerine hayatı boyunca sadece bir kere bağlantı yapmasını ve sürekli onu kullanmasını sağlarlar. Bu demektir ki, kalıcı bağlantı açan her çocuk işlemin kendisine ait SQL sunucusuna kalıcı bir bağlantısı olacaktır. Örneğin, 20 tane kalıcı bağlantı açan betik çalıştırmış farklı çocuk işlem varsa, SQL sunucusuna, her çocuk işlemden bir tane olmak üzere, 20 tane bağlantı olacaktır.
Ancak dikkat edin ki, SQL sunucusunun bağlantı limiti kalıcı bağlantılarla aşıldığında bunun bir takım götürüleri olacaktır. Eğer veritabanı sunucunuz ayni anda 16 bağlantıya izin veriyorsa, ve yoğun bir çalışma anında 17 çocuk işlem kalıcı bağlantı açmaya kalkarsa, bunlardan biri bağlantıyı açamaz. Eğer betiklerinizde bağlantıların kapanabilmesine olanak tanımayan hatalar varsa (kısır döngüler gibi), 32 bağlantıya izin veren bir veritabanı sunucusu çok çabuk bir şekilde kullanım dışı olur. Boş duran (idle) bağlantılarla nasıl ilgileneceğiniz konusunda veritabanınızın dökümanlarına başvurun.
| Uyarı |
Kalıcı bağlantı kullanırken akılda tutulması gereken birkaç ek götürü daha var. Örneğin kalıcı bir bağlantı üzerinden bir tablo kitlendiyse (LOCK), ve betik herhangi bir sebepten dolayı kilidi kaldıramıyorsa, ardısıra gelen ve aynı bağlantıyı kullanacak betikler süresiz olarak bloke olacak, ve sizin ya HTTP sunucusunu ya da veritabanı sunucusunu baştan çalıştırmanız gerekecektir. Başka bir götürü transaction kullanırken oluşabilir. Bir transaction bloğu, betiğin çalışma süresi bloğun ömründen kisaysa, bir sonraki betiğe taşınacaktır. İki durumda da register_shutdown_function() ile transaction'i geri alacak ya da tablo kilitlerini kaldıracak bir temizlik fonksiyonu kaydedebilirsiniz. Daha iyisi, problemleri tümüyle önlemek için tablo kilitleri veya transaction kullanan betiklerde kalıcı bağlantıları kullanmamaktır (başka yerlerde hala kullanabilirsiniz). |
Önemli bir özet. Kalıcı bağlantılar normal bağlantılarla birebir eşlenebilecek şekilde tasarlandı. Bu demektir ki her zaman kalıcı bağlantıları normal olanlarla değiştirebilirsiniz, ve bu betiklerin davranışlarını etkilemeyecektir. Betiklerin etkinliklerini belki değiştirebilirler, fakat davranışını değiştirmezler!
Kalıcı Veritabanı Bağlantıları
26-Jun-2007 10:46
20-Feb-2007 08:13
To those using MySQL and finding a lot of leftover sleeping processes, take a look at MySQL's wait_timeout directive. By default it is set to 8 hours, but almost any decent production server will have been lowered to the 60 second range. Even on my testing server, I was having problems with too many connections from leftover persistent connections.
26-Nov-2006 03:02
in response to web at nick, have you tried FLUSH PRIVILEGES. this should reload those privileges.
06-Mar-2006 03:43
If you have multiple databases on the same server AND you are using persistent connections, you MUST prefix all the table names with the specific database name.
Changing the database using the xxx_select_db functions alters the database for the connection for all users who are sharing that connection (assuming PHP is running shared and not CGI/CLI).
If you have 2 databases (live and archive) and your script is talking to both, you cannot use 2 persistent connections and change the database for each one.
Internally, persistent connections are used even if you do not specify that you want to use persistent connections. This is why new_link was added to mysql_connect/mssql_connect (PHPV4.2.0+).
12-Jan-2006 03:54
You can in fact provide a port for the connection, take a look at http://de2.php.net/manual/en/function.mysql-pconnect.php#AEN101879
Just use "hostname:port" for the server address.
15-Jan-2004 03:21
this one bit quite a bit of chunk out of my you-know-what. seems like if you're running multiple database servers on the same host (for eg. MySQL on a number of ports) you can't use pconnect since the port number isn't part of the key for database connections. especially if you have the same username and password to connect to all the database servers running on different ports. but then it might be php-MySQL specific. you might get a connection for an entirely different port than the one you asked for.
02-Dec-2003 02:41
This may only pertain to Apache/MySQL:
After several hours of wrestling with MySQL "Access denied" messages, I determined that persistent database connections don't necessarily reflect subsequent privilege changes.
I loaded a PHP script attempting a LOAD DATA statement, and got an "Access denied" error. I granted FILE privileges to the MySQL user, and was able to run LOAD DATA statements from the terminal, but still got "Access denied" from my PHP pages. When I switched from mysql_pconnect() to mysql_connect(), the problem went away; eventually I restarted apache to kill the persistent connection and switched back to mysql_pconnect(), and now everything works fine.
15-Aug-2002 03:13
If anyone ever wonders why the number of idle db process (open connections) seems to grow even though you are using persistent connections, here's why:
"You are probably using a multi-process web server such as Apache. Since
database connections cannot be shared among different processes a new
one is created if the request happen to come to a different web server
child process."
18-Apr-2000 07:28
Yes, with nonpersistent connections database connections last only while a database-related request is processed, thus reducing the load on the database server.
However, latency will be somewhat higher since a database connection must be opened before a request can be handeled.
